/*
 * Copyright 2015 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.common.app;

import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onlab.util.Tools;
import org.onosproject.app.ApplicationDescription;
import org.onosproject.app.ApplicationException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

import static org.junit.Assert.*;
import static org.onosproject.app.DefaultApplicationDescriptionTest.*;

/**
 * Suite of tests for the application archive utility.
 */
public class ApplicationArchiveTest {

    static final File STORE = Files.createTempDir();

    private ApplicationArchive aar = new ApplicationArchive();

    @Before
    public void setUp() {
        aar.setRootPath(STORE.getAbsolutePath());
    }

    @After
    public void tearDown() throws IOException {
        if (STORE.exists()) {
            Tools.removeDirectory(STORE);
        }
    }

    private void validate(ApplicationDescription app) {
        assertEquals("incorrect name", APP_NAME, app.name());
        assertEquals("incorrect version", VER, app.version());
        assertEquals("incorrect origin", ORIGIN, app.origin());
        assertEquals("incorrect role", ROLE, app.role());

        assertEquals("incorrect category", CATEGORY, app.category());
        assertEquals("incorrect url", URL, app.url());
        assertEquals("incorrect readme", README, app.readme());

        assertEquals("incorrect description", DESC, app.description());
        assertEquals("incorrect features URI", FURL, app.featuresRepo().get());
        assertEquals("incorrect permissions", PERMS, app.permissions());
        assertEquals("incorrect features", FEATURES, app.features());
    }

    @Test
    public void saveZippedApp() throws IOException {
        InputStream stream = getClass().getResourceAsStream("app.zip");
        ApplicationDescription app = aar.saveApplication(stream);
        validate(app);
        stream.close();
    }

    @Test
    public void savePlainApp() throws IOException {
        InputStream stream = getClass().getResourceAsStream("app.xml");
        ApplicationDescription app = aar.saveApplication(stream);
        validate(app);
        stream.close();
    }

    @Test
    public void loadApp() throws IOException {
        saveZippedApp();
        ApplicationDescription app = aar.getApplicationDescription(APP_NAME);
        validate(app);
    }

    @Test
    public void getAppNames() throws IOException {
        saveZippedApp();
        Set<String> names = aar.getApplicationNames();
        assertEquals("incorrect names", ImmutableSet.of(APP_NAME), names);
    }

    @Test
    public void purgeApp() throws IOException {
        saveZippedApp();
        aar.purgeApplication(APP_NAME);
        assertEquals("incorrect names", ImmutableSet.<String>of(),
                     aar.getApplicationNames());
    }

    @Test
    public void getAppZipStream() throws IOException {
        saveZippedApp();
        InputStream stream = aar.getApplicationInputStream(APP_NAME);
        byte[] orig = ByteStreams.toByteArray(getClass().getResourceAsStream("app.zip"));
        byte[] loaded = ByteStreams.toByteArray(stream);
        assertArrayEquals("incorrect stream", orig, loaded);
        stream.close();
    }

    @Test
    public void getAppXmlStream() throws IOException {
        savePlainApp();
        InputStream stream = aar.getApplicationInputStream(APP_NAME);
        byte[] orig = ByteStreams.toByteArray(getClass().getResourceAsStream("app.xml"));
        byte[] loaded = ByteStreams.toByteArray(stream);
        assertArrayEquals("incorrect stream", orig, loaded);
        stream.close();
    }

    @Test
    public void active() throws IOException {
        savePlainApp();
        assertFalse("should not be active", aar.isActive(APP_NAME));
        aar.setActive(APP_NAME);
        assertTrue("should not be active", aar.isActive(APP_NAME));
        aar.clearActive(APP_NAME);
        assertFalse("should not be active", aar.isActive(APP_NAME));
    }

    @Test(expected = ApplicationException.class)
    public void getBadAppDesc() throws IOException {
        aar.getApplicationDescription("org.foo.BAD");
    }

    @Test(expected = ApplicationException.class)
    public void getBadAppStream() throws IOException {
        aar.getApplicationInputStream("org.foo.BAD");
    }

    @Test(expected = ApplicationException.class)
    @Ignore("No longer needed")
    public void setBadActive() throws IOException {
        aar.setActive("org.foo.BAD");
    }

    @Test // (expected = ApplicationException.class)
    public void purgeBadApp() throws IOException {
        aar.purgeApplication("org.foo.BAD");
    }

}