/**
 * Copyright (c) 2008-2011, http://www.snakeyaml.org
 *
 * 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.constructor;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Util;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;

public class ImplicitTagsTest extends TestCase {

    public void testDefaultRepresenter() throws IOException {
        CarWithWheel car1 = new CarWithWheel();
        car1.setPlate("12-XP-F4");
        Wheel wheel = new Wheel();
        wheel.setId(2);
        car1.setWheel(wheel);
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("id", 3);
        car1.setMap(map);
        car1.setPart(new Wheel(4));
        car1.setYear("2008");
        String carYaml1 = new Yaml().dump(car1);
        assertEquals(Util.getLocalResource("constructor/carwheel-without-tags.yaml"), carYaml1);
        CarWithWheel car2 = (CarWithWheel) new Yaml().load(carYaml1);
        String carYaml2 = new Yaml().dump(car2);
        assertEquals(carYaml1, carYaml2);
    }

    public void testNoRootTag() throws IOException {
        CarWithWheel car1 = new CarWithWheel();
        car1.setPlate("12-XP-F4");
        Wheel wheel = new Wheel();
        wheel.setId(2);
        car1.setWheel(wheel);
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("id", 3);
        car1.setMap(map);
        car1.setYear("2008");
        String carYaml1 = new Yaml().dumpAs(car1, Tag.MAP);
        assertEquals(Util.getLocalResource("constructor/car-without-root-tag.yaml"), carYaml1);
        //
        Constructor contructor = new Constructor(CarWithWheel.class);
        CarWithWheel car2 = (CarWithWheel) new Yaml(contructor).load(carYaml1);
        String carYaml2 = new Yaml().dumpAs(car2, Tag.MAP);
        assertEquals(carYaml1, carYaml2);
    }

    @SuppressWarnings("unchecked")
    public void testRootMap() throws IOException {
        Map<Object, Object> car1 = new HashMap<Object, Object>();
        car1.put("plate", "12-XP-F4");
        Wheel wheel = new Wheel();
        wheel.setId(2);
        car1.put("wheel", wheel);
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("id", 3);
        car1.put("map", map);
        String carYaml1 = new Yaml().dump(car1);
        assertEquals(Util.getLocalResource("constructor/carwheel-root-map.yaml"), carYaml1);
        Map<Object, Object> car2 = (Map<Object, Object>) new Yaml().load(carYaml1);
        assertEquals(car1, car2);
        assertEquals(carYaml1, new Yaml().dump(car2));
    }

    public void testLoadClassTag() throws IOException {
        Constructor constructor = new Constructor();
        constructor.addTypeDescription(new TypeDescription(Car.class, "!car"));
        Yaml yaml = new Yaml(constructor);
        Car car = (Car) yaml.load(Util.getLocalResource("constructor/car-without-tags.yaml"));
        assertEquals("12-XP-F4", car.getPlate());
        List<Wheel> wheels = car.getWheels();
        assertNotNull(wheels);
        assertEquals(5, wheels.size());
        Wheel w1 = wheels.get(0);
        assertEquals(1, w1.getId());
        //
        String carYaml1 = new Yaml().dump(car);
        assertTrue(carYaml1.startsWith("!!org.yaml.snakeyaml.constructor.Car"));
        //
        Representer representer = new Representer();
        representer.addClassTag(Car.class, new Tag("!car"));
        yaml = new Yaml(representer);
        String carYaml2 = yaml.dump(car);
        assertEquals(Util.getLocalResource("constructor/car-without-tags.yaml"), carYaml2);
    }

    public static class CarWithWheel {
        private String plate;
        private String year;
        private Wheel wheel;
        private Object part;
        private Map<String, Integer> map;

        public String getPlate() {
            return plate;
        }

        public void setPlate(String plate) {
            this.plate = plate;
        }

        public Wheel getWheel() {
            return wheel;
        }

        public void setWheel(Wheel wheel) {
            this.wheel = wheel;
        }

        public Map<String, Integer> getMap() {
            return map;
        }

        public void setMap(Map<String, Integer> map) {
            this.map = map;
        }

        public Object getPart() {
            return part;
        }

        public void setPart(Object part) {
            this.part = part;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }
    }
}
