/*
 * Copyright 2012-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.json;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Unit test for {@link BuildFileToJsonParser}.
 */
public class BuildFileToJsonParserTest {

  @Test
  public void testSimpleParse() throws IOException {
    String json =
        "[" +
        "{" +
          "\"srcs\": [\"src/com/facebook/buck/Bar.java\", \"src/com/facebook/buck/Foo.java\"]" +
        "}" +
        "]";

    try (BuildFileToJsonParser parser = new BuildFileToJsonParser(json)) {
      assertEquals(
          ImmutableList.of(
              ImmutableMap.of("srcs",
                  ImmutableList.of(
                      "src/com/facebook/buck/Bar.java",
                      "src/com/facebook/buck/Foo.java"))),
          parser.nextRules());
    }
  }

  @Test
  public void testParseLong() throws IOException {
    String json = "[{\"thing\": 27}]";
    List<Map<String, Object>> tokens;
    try (BuildFileToJsonParser parser = new BuildFileToJsonParser(json)) {
      tokens = parser.nextRules();
    }

    assertEquals(1, tokens.size());
    Map<String, Object> rule = tokens.get(0);
    Object value = rule.get("thing");
    assertEquals(Long.class, value.getClass());
    assertEquals(27L, rule.get("thing"));
    assertNotEquals(27, rule.get("thing"));
  }

  @Test
  public void testParseNestedStructures() throws IOException {
    String json =
        "[" +
         "{" +
             "\"foo\": [\"a\", \"b\"]," +
             "\"bar\": {\"baz\": \"quox\"}" +
         "}" +
        "]";

    try (BuildFileToJsonParser parser = new BuildFileToJsonParser(json)) {
      assertEquals(
          ImmutableList.of(ImmutableMap.of(
              "foo", ImmutableList.of("a", "b"),
              "bar", ImmutableMap.of("baz", "quox"))),
          parser.nextRules());
    }
  }

  @Test
  public void testToRawTypes() {
    JsonObject ruleJson = new JsonObject();

    ruleJson.addProperty("name", "foo");
    ruleJson.addProperty("export_deps", false);
    ruleJson.addProperty("proguard_config", (String) null);
    ruleJson.addProperty("source", 6);

    JsonArray deps = new JsonArray();
    deps.add(new JsonPrimitive("//foo:bar"));
    deps.add(new JsonPrimitive("//foo:baz"));
    deps.add(new JsonPrimitive("//foo:biz"));
    ruleJson.add("deps", deps);

    // Note that an ImmutableMap does not allow null values, but BuildFileToJsonParser.toRawTypes()
    // can return a Map with null values, so we use an ordinary HashMap for the expected value.
    Map<String, Object> expected = Maps.newHashMap();
    expected.put("name", "foo");
    expected.put("export_deps", false);
    expected.put("proguard_config", null);
    expected.put("source", 6L);
    expected.put("deps", ImmutableList.of("//foo:bar", "//foo:baz", "//foo:biz"));
    assertEquals(expected, RawParser.toRawTypes(ruleJson));
  }
}
