/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.channel.cc.commons.spring;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.createTempFile;
import static java.nio.file.Files.deleteIfExists;
import static java.nio.file.Files.exists;
import static java.nio.file.Files.write;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * Tests of {@link Applications}.
 */
public class ApplicationsTest {
    private static final String[] ARGS = {"args" };

    private static final String SPRING_CONFIG_LOCATION =
        "--spring.config.location=";

    @Test
    public void testRunFailure() {
        assertEquals(3, Applications.run(FailureApplication.class, ARGS));
    }

    @Test
    public void testRunOK() {
        assertEquals(0, Applications.run(OKApplication.class, ARGS));
    }

    @Test
    public void testRunSensitive() throws IOException {
        Path configFile = createTempFile("config", ".properties");
        try {
            write(configFile, "key=value".getBytes(UTF_8));
            String[] args =
                {SPRING_CONFIG_LOCATION + configFile.toUri().toString() };
            assertEquals(0,
                Applications.run(SensitiveApplication.class, args, true));
        } finally {
            deleteIfExists(configFile);
        }
    }

    @Configuration
    public static class FailureApplication implements Application {

        @Override
        public void run(String[] args) throws ApplicationException {
            ApplicationException exception =
                new ApplicationException("test1", 1);
            exception.addSuppressed(new ApplicationException("test2", 2));
            exception.addSuppressed(new ApplicationException("test3", 3));
            throw exception;
        }

        @Override
        public void shutdown() {
            throw new UnsupportedOperationException();

        }

        @Override
        public void shutdown(Throwable e) {
            throw new UnsupportedOperationException();
        }
    }

    @Configuration
    public static class OKApplication implements Application {

        @Override
        public void run(String[] args) throws ApplicationException {
            assertArrayEquals(ARGS, args);
        }

        @Override
        public void shutdown() {
            throw new UnsupportedOperationException();

        }

        @Override
        public void shutdown(Throwable e) {
            throw new UnsupportedOperationException();
        }
    }

    @Configuration
    public static class SensitiveApplication implements Application {
        @Value("${key}")
        private String value;

        @Override
        public void run(String[] args) throws ApplicationException {
            assertTrue(args[0].startsWith(SPRING_CONFIG_LOCATION));
            
            assertEquals("value", value);
            
            String location =
                args[0].substring(SPRING_CONFIG_LOCATION.length());
            URI uri;
            try {
                uri = new URI(location);
            } catch (URISyntaxException e) {
                throw new AssertionError(e);
            }
            Path file = Paths.get(uri);
            assertFalse(exists(file));
        }

        @Override
        public void shutdown() {
            throw new UnsupportedOperationException();

        }

        @Override
        public void shutdown(Throwable e) {
            throw new UnsupportedOperationException();
        }
    }
}
