package com.yammer.dropwizard.cli.tests;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.yammer.dropwizard.AbstractService;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.cli.ConfiguredCommand;
import com.yammer.dropwizard.config.Configuration;

import com.yammer.dropwizard.config.Environment;
import java.io.File;
import java.io.IOException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import org.hibernate.validator.constraints.NotEmpty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

public class ConfiguredCommandTest {

    public static class MyConfig extends Configuration {

        @NotEmpty
        private String type;

        public String getType() {
            return type;
        }
    }

    static class MyService extends Service<MyConfig> {
        public MyService() {
            super("myservice");
        }

        @Override
        protected void initialize(MyConfig configuration, Environment environment) throws Exception {
        }
    }

    static class DirectCommand extends ConfiguredCommand<MyConfig> {
        private String type, tag;
        private boolean verbose = false;

        protected DirectCommand() {
            super("test", "foobar");
        }

        @Override
        public Options getOptions() {
            return super.getOptions()
                .addOption("t", "tag", true, "Arbitrary tag")
                .addOption("v", "verbose", false, "Verbose flag");
        }

        @Override
        protected void run(AbstractService<MyConfig> service,
                           MyConfig configuration, CommandLine params) {
            this.type = configuration.getType();
            this.tag = params.getOptionValue("tag");
            this.verbose = params.hasOption("verbose");
        }

        // needed since super-class method is protected
        public Class<?> getParameterization() {
            return super.getConfigurationClass();
        }

        public String getType() {
            return type;
        }

        public String getTag() {
            return tag;
        }

        public boolean isVerbose() {
            return verbose;
        }
    }


    static class UberCommand extends DirectCommand {
    }

    @Test
    public void canResolveDirectParameterization() {
        assertEquals(new DirectCommand().getParameterization(), MyConfig.class);
    }

    @Test
    public void canResolveIndirectParameterization() {
        assertEquals(new UberCommand().getParameterization(), MyConfig.class);
    }

    @Test
    public void parseYmlConfigFile() throws Exception {
        String ymlConfigFile = createTemporaryFile(".yml", "type: yml\n");

        DirectCommand command = new DirectCommand();
        command.run(new MyService(), new String[]{ymlConfigFile});

        assertThat(command.getType(), is("yml"));
        assertNull(command.getTag());
        assertFalse(command.isVerbose());
    }

    @Test
    public void parseJsonConfigFile() throws Exception {
        String jsonConfigFile = createTemporaryFile(".json", "{\"type\": \"json\"}");

        DirectCommand command = new DirectCommand();
        command.run(new MyService(), new String[]{jsonConfigFile});

        assertThat(command.getType(), is("json"));
    }

    @Test
    public void argumentsAreParsedAsExpected() throws Exception {
        String jsonConfigFile = createTemporaryFile(".json", "{\"type\": \"json2\"}");

        DirectCommand command = new DirectCommand();
        command.run(new MyService(), new String[]{jsonConfigFile, "-v", "--tag", "tag1"});

        assertThat(command.getType(), is("json2"));
        assertThat(command.getTag(), is("tag1"));
        assertTrue(command.isVerbose());
    }

    /**
     * @return absolute path to temporary file
     */
    private String createTemporaryFile(String extension, String content) throws IOException {
        File file = File.createTempFile("dropwizard", extension);
        file.deleteOnExit();

        Files.write(content, file, Charsets.UTF_8);
        return file.getAbsolutePath();
    }

}

@@ -297,17 +297,16 @@
 ration;%0A
-%0A
 import c
@@ -350,57 +350,8 @@
 nt;%0A
-import java.io.File;%0Aimport java.io.IOException;%0A
 impo
@@ -439,191 +439,152 @@
 ort 
-static org.hamcrest.MatcherAssert.assertThat;%0Aimport static org.hamcrest.Matchers.is;%0Aimport org.hibernate.validator.constraints.NotEmpty;%0Aimport static org.junit.Assert.assertEquals;
+org.hibernate.validator.constraints.NotEmpty;%0Aimport org.junit.Ignore;%0Aimport org.junit.Test;%0A%0Aimport java.io.File;%0Aimport java.io.IOException;%0A
 %0Aimp
@@ -590,38 +590,48 @@
 port static org.
-junit.
+hamcrest.Matcher
 Assert.assertFal
@@ -627,21 +627,20 @@
 t.assert
-False
+That
 ;%0Aimport
@@ -655,31 +655,28 @@
 org.
-junit.Assert.assertNull
+hamcrest.Matchers.is
 ;%0Aim
@@ -708,43 +708,67 @@
 ert.
-assertTrue;%0Aimport org.junit.Test;%0A
+*;%0A%0A@Ignore(%22DW lifecycle doesn't play well with Surefire%22)
 %0Apub

Disable ConfiguredCommandTest.