/*
 * Copyright 2015-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.onlab.stc;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.stc.MonitorLayout.Box;

import java.io.IOException;

import static org.junit.Assert.assertEquals;
import static org.onlab.stc.CompilerTest.getStream;
import static org.onlab.stc.CompilerTest.stageTestResource;
import static org.onlab.stc.MonitorLayout.SLOT_WIDTH;
import static org.onlab.stc.Scenario.loadScenario;

/**
 * Tests of the monitor layout functionality.
 */
public class MonitorLayoutTest {

    private MonitorLayout layout;

    @BeforeClass
    public static void setUpClass() throws IOException {
        CompilerTest.setUpClass();
    }

    @AfterClass
    public static void tearDownClass() throws IOException {
        CompilerTest.tearDownClass();
    }

    private Compiler getCompiler(String name) throws IOException {
        stageTestResource(name);
        Scenario scenario = loadScenario(getStream(name));
        Compiler compiler = new Compiler(scenario);
        compiler.compile();
        return compiler;
    }

    @Test
    public void basic() throws IOException {
        layout = new MonitorLayout(getCompiler("layout-basic.xml"));
        validate(layout, null, 0, 1, 5, 2);
        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
        validate(layout, "b", 2, 2, 1, 1, 0, 0);
        validate(layout, "f", 3, 3, 1);

        validate(layout, "g", 1, 1, 4, 1, 1, SLOT_WIDTH / 2);
        validate(layout, "c", 2, 1, 1);
        validate(layout, "d", 3, 2, 1);
        validate(layout, "e", 4, 3, 1);
    }

    @Test
    public void basicNest() throws IOException {
        layout = new MonitorLayout(getCompiler("layout-basic-nest.xml"));
        validate(layout, null, 0, 1, 6, 2);
        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
        validate(layout, "b", 2, 2, 1);
        validate(layout, "f", 3, 3, 1);

        validate(layout, "g", 1, 1, 5, 1);
        validate(layout, "c", 2, 1, 1);

        validate(layout, "gg", 3, 2, 3, 1);
        validate(layout, "d", 4, 1, 1);
        validate(layout, "e", 5, 2, 1);
    }

    @Test
    public void staggeredDependencies() throws IOException {
        layout = new MonitorLayout(getCompiler("layout-staggered-dependencies.xml"));
        validate(layout, null, 0, 1, 7, 4);
        validate(layout, "a", 1, 1, 1, 1, 1, -SLOT_WIDTH - SLOT_WIDTH / 2);
        validate(layout, "aa", 1, 1, 1, 1, 1, -SLOT_WIDTH / 2);
        validate(layout, "b", 2, 2, 1);
        validate(layout, "f", 3, 3, 1);

        validate(layout, "g", 1, 1, 5, 2, 1, +SLOT_WIDTH / 2);
        validate(layout, "c", 2, 1, 1);

        validate(layout, "gg", 3, 2, 3, 2);
        validate(layout, "d", 4, 1, 1);
        validate(layout, "dd", 4, 1, 1);
        validate(layout, "e", 5, 2, 1);

        validate(layout, "i", 6, 6, 1);
    }

    @Test
    public void deepNext() throws IOException {
        layout = new MonitorLayout(getCompiler("layout-deep-nest.xml"));
        validate(layout, null, 0, 1, 7, 6);
        validate(layout, "a", 1, 1, 1);
        validate(layout, "aa", 1, 1, 1);
        validate(layout, "b", 2, 2, 1);
        validate(layout, "f", 3, 3, 1);

        validate(layout, "g", 1, 1, 5, 2);
        validate(layout, "c", 2, 1, 1);

        validate(layout, "gg", 3, 2, 3, 2);
        validate(layout, "d", 4, 1, 1);
        validate(layout, "dd", 4, 1, 1);
        validate(layout, "e", 5, 2, 1);

        validate(layout, "i", 6, 6, 1);

        validate(layout, "g1", 1, 1, 6, 2);
        validate(layout, "g2", 2, 1, 5, 2);
        validate(layout, "g3", 3, 1, 4, 2);
        validate(layout, "u", 4, 1, 1);
        validate(layout, "v", 4, 1, 1);
        validate(layout, "w", 5, 2, 1);
        validate(layout, "z", 6, 3, 1);
    }


    private void validate(MonitorLayout layout, String name,
                          int absoluteTier, int tier, int depth, int breadth) {
        Box b = layout.get(name);
        assertEquals("incorrect absolute tier", absoluteTier, b.absoluteTier());
        assertEquals("incorrect tier", tier, b.tier());
        assertEquals("incorrect depth", depth, b.depth());
        assertEquals("incorrect breadth", breadth, b.breadth());
    }

    private void validate(MonitorLayout layout, String name,
                          int absoluteTier, int tier, int depth, int breadth,
                          int top, int center) {
        validate(layout, name, absoluteTier, tier, depth, breadth);
        Box b = layout.get(name);
        assertEquals("incorrect top", top, b.top());
        assertEquals("incorrect center", center, b.center());
    }

    private void validate(MonitorLayout layout, String name,
                          int absoluteTier, int tier, int depth) {
        validate(layout, name, absoluteTier, tier, depth, 1);
    }

}