/**
 * Copyright (c) 2008, SnakeYAML
 *
 * 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 org.yaml.snakeyaml.extensions.compactnotation;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.yaml.snakeyaml.Util;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

public class CompactConstructorExampleTest extends TestCase {

  private Object load(String fileName) {
    CompactConstructor compact = new CompactConstructor();
    Yaml yaml = new Yaml(compact);
    String doc = Util.getLocalResource("compactnotation/" + fileName);
    Object obj = yaml.load(doc);
    assertNotNull(obj);
    return obj;
  }

  public void test1() {
    Object obj = load("example1.yaml");
    assertEquals(new Container(), obj);
  }

  public void test2() {
    Object obj = load("example2.yaml");
    assertEquals(new Container("title"), obj);
  }

  public void test3() {
    Container obj = (Container) load("example3.yaml");
    assertEquals(new Container("title3"), obj);
    assertEquals("title3", obj.getTitle());
    assertEquals("parent", obj.getName());
    assertEquals("123", obj.getId());
  }

  public void test4() {
    Object obj = load("example4.yaml");
    // System.out.println(obj);
    Container container = (Container) obj;
    assertNotNull(obj);
    assertEquals(new Container("title4"), obj);
    assertEquals("title4", container.getTitle());
    assertEquals("child4", container.getName());
    assertEquals("444", container.getId());
  }

  public void test5() {
    Object obj = load("example5.yaml");
    // System.out.println(obj);
    Container container = (Container) obj;
    assertNotNull(obj);
    assertEquals(new Container("title4"), obj);
    assertEquals("title4", container.getTitle());
    assertEquals("child5", container.getName());
    assertEquals("ID555", container.getId());
  }

  public void test6() {
    Object obj = load("example6.yaml");
    // System.out.println(obj);
    Container container = (Container) obj;
    assertNotNull(obj);
    assertEquals(new Container("title4"), obj);
    assertEquals("title4", container.getTitle());
    assertEquals("child6", container.getName());
    assertEquals("ID6", container.getId());
  }

  public void test7() {
    Object obj = load("example7.yaml");
    // System.out.println(obj);
    Container container = (Container) obj;
    assertNotNull(obj);
    assertEquals(new Container("The title"), obj);
    assertEquals("The title", container.getTitle());
    assertEquals("child7", container.getName());
    assertEquals("id7", container.getId());
  }

  @SuppressWarnings("unchecked")
  // TODO it is unclear how the result should look like for CON
  public void test9() {
    Map<String, Object> map = (Map<String, Object>) load("example9.yaml");
    assertEquals(1, map.size());
    Map<Container, Map<String, String>> containers =
        (Map<Container, Map<String, String>>) map.get("something");
    // System.out.println(obj);
    assertEquals(2, containers.size());
    for (Container c : containers.keySet()) {
      assertTrue(c.getId().matches("id\\d"));
      assertEquals(1, containers.get(c).size());
    }
  }

  @SuppressWarnings("unchecked")
  public void test10() {
    Map<String, Object> map = (Map<String, Object>) load("example10.yaml");
    assertEquals(1, map.size());
    List<Container> containers = (List<Container>) map.get("something");
    // System.out.println(obj);
    assertEquals(3, containers.size());
    for (Container c : containers) {
      assertTrue(c.toString(), c.getId().matches("id\\d+"));
      assertTrue(c.toString(), c.getName().matches("child\\d+"));
      // System.out.println(c);
    }
  }

  public void test11withoutPackageNames() {
    Constructor compact =
        new PackageCompactConstructor("org.yaml.snakeyaml.extensions.compactnotation");
    Yaml yaml = new Yaml(compact);
    String doc = Util.getLocalResource("compactnotation/example11.yaml");
    Box box = yaml.load(doc);
    assertNotNull(box);
    assertEquals("id11", box.getId());
    assertEquals("Main box", box.getName());
    Item top = box.getTop();
    assertEquals("id003", top.getId());
    assertEquals("25.0", top.getPrice());
    assertEquals("parrot", top.getName());
    Item bottom = box.getBottom();
    assertEquals("id004", bottom.getId());
    assertEquals("3.5", bottom.getPrice());
    assertEquals("sweet", bottom.getName());
  }

  public void test12withList() {
    Constructor compact =
        new TableCompactConstructor("org.yaml.snakeyaml.extensions.compactnotation");
    Yaml yaml = new Yaml(compact);
    String doc = Util.getLocalResource("compactnotation/example12.yaml");
    Table table = yaml.load(doc);
    assertNotNull(table);
    assertEquals("id12", table.getId());
    assertEquals("A table", table.getName());
    List<Row> rows = table.getRows();
    assertEquals(3, rows.size());
    Iterator<Row> iter = rows.iterator();
    Row first = iter.next();
    assertEquals("id111", first.getId());
    assertEquals("I think; therefore I am.", first.getDescription());
    assertEquals(0.125, first.getRatio(), 0.000000001);
    assertEquals(15, first.getSize());
    Row second = iter.next();
    assertEquals("id222", second.getId());
    assertEquals("We do not need new lines here, just replace them all with spaces\n",
        second.getDescription());
    assertEquals(0.333, second.getRatio(), 0.000000001);
    assertEquals(17, second.getSize());
    Row third = iter.next();
    assertEquals("id333", third.getId());
    assertEquals(
        "Please preserve all\nthe lines because they may be\nimportant, but do not include the last one !!!",
        third.getDescription());
    assertEquals(0.88, third.getRatio(), 0.000000001);
    assertEquals(52, third.getSize());
  }
}
