/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.onosproject.net.config.basics;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.onosproject.net.config.basics.BasicElementConfig.ZERO_THRESHOLD;

/**
 * Unit tests for {@link BasicElementConfig}.
 */
public class BasicElementConfigTest {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    private static final String E1 = "e1";
    private static final String GEO = "geo";
    private static final String GRID = "grid";

    // concrete subclass of abstract class we are testing
    private static class ElmCfg extends BasicElementConfig<String> {
        ElmCfg() {
            object = MAPPER.createObjectNode();
        }

        @Override
        public String toString() {
            return object.toString();
        }
    }

    private static void print(String fmt, Object... args) {
        System.out.println(String.format(fmt, args));
    }

    private static void print(Object o) {
        print("%s", o);
    }

    private BasicElementConfig<?> cfg;

    @Before
    public void setUp() {
        cfg = new ElmCfg().name(E1);
    }

    @Test
    public void basicNoGeo() {
        print(cfg);
        assertFalse("geo set?", cfg.geoCoordsSet());
        assertEquals("lat", 0.0, cfg.latitude(), ZERO_THRESHOLD);
        assertEquals("lon", 0.0, cfg.longitude(), ZERO_THRESHOLD);
    }

    @Test
    public void geoLatitudeOnly() {
        cfg.latitude(0.1);
        print(cfg);
        assertTrue("geo NOT set", cfg.geoCoordsSet());
        assertEquals("lat", 0.1, cfg.latitude(), ZERO_THRESHOLD);
        assertEquals("lon", 0.0, cfg.longitude(), ZERO_THRESHOLD);
    }

    @Test
    public void geoLongitudeOnly() {
        cfg.longitude(-0.1);
        print(cfg);
        assertTrue("geo NOT set", cfg.geoCoordsSet());
        assertEquals("lat", 0.0, cfg.latitude(), ZERO_THRESHOLD);
        assertEquals("lon", -0.1, cfg.longitude(), ZERO_THRESHOLD);
    }

    @Test
    public void geoLatLong() {
        cfg.latitude(3.1415).longitude(2.71828);
        print(cfg);
        assertTrue("geo NOT set", cfg.geoCoordsSet());
        assertEquals("lat", 3.1415, cfg.latitude(), ZERO_THRESHOLD);
        assertEquals("lon", 2.71828, cfg.longitude(), ZERO_THRESHOLD);
    }

    @Test
    public void uiType() {
        print(cfg);
        assertEquals("not default type", null, cfg.uiType());
        cfg.uiType("someOtherType");
        print(cfg);
        assertEquals("not other type", "someOtherType", cfg.uiType());
    }

    @Test
    public void defaultGridCoords() {
        print(cfg);
        assertEquals("gridx", 0.0, cfg.gridX(), ZERO_THRESHOLD);
        assertEquals("gridy", 0.0, cfg.gridY(), ZERO_THRESHOLD);
    }

    @Test
    public void someGridCoords() {
        cfg.gridX(35.0).gridY(49.7);
        print(cfg);
        assertEquals("gridx", 35.0, cfg.gridX(), ZERO_THRESHOLD);
        assertEquals("gridy", 49.7, cfg.gridY(), ZERO_THRESHOLD);
    }

    @Test
    public void defaultLocationType() {
        print(cfg);
        assertEquals("not geo", GEO, cfg.locType());
    }

    @Test
    public void geoLocationType() {
        cfg.locType(GEO);
        print(cfg);
        assertEquals("not geo", GEO, cfg.locType());
    }

    @Test
    public void gridLocationType() {
        cfg.locType(GRID);
        print(cfg);
        assertEquals("not grid", GRID, cfg.locType());
    }

    @Test
    public void otherLocationType() {
        cfg.locType("foobar");
        print(cfg);
        assertEquals("not geo", GEO, cfg.locType());
    }
}
