package picocli;

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ProvideSystemProperty;
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
import org.junit.rules.TestRule;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import static org.junit.Assert.*;

public class ModelTypedMemberTest {

    // allows tests to set any kind of properties they like, without having to individually roll them back
    @Rule
    public final TestRule restoreSystemProperties = new RestoreSystemProperties();

    @Rule
    public final ProvideSystemProperty ansiOFF = new ProvideSystemProperty("picocli.ansi", "false");

    @Test
    public void testInferTypes() {
        class App {
            @CommandLine.Parameters
            List<Class<? extends Class<? extends String>[]>> list;
        }
        assertEquals("<list>", CommandLine.Model.CommandSpec.forAnnotatedObject(new App()).positionalParameters().get(0).paramLabel());
    }

    @Test
    public void testTypedMemberGetAuxiliaryTypes() throws Exception {
        class App {
            @CommandLine.Option(names = "-x") public char x;
        }
        Field f = App.class.getDeclaredField("x");
        CommandLine.Model.TypedMember typedMember = new CommandLine.Model.TypedMember(f);
        assertArrayEquals(new Class[]{char.class}, typedMember.getAuxiliaryTypes());

        assertEquals(-1, typedMember.getMethodParamPosition());
    }

    @Test
    public void testTypedMemberGetMethodParamPosition() throws Exception {
        class App {
            @CommandLine.Command
            public void mymethod(@CommandLine.Option(names = "-x") char x) {}
        }
        Method method = App.class.getDeclaredMethod("mymethod", char.class);
        CommandLine.Model.MethodParam param = new CommandLine.Model.MethodParam(method, 0);

        CommandLine.Model.TypedMember typedMember = new CommandLine.Model.TypedMember(param, new CommandLine.Model.ObjectScope(new App()));
        assertEquals(0, typedMember.getMethodParamPosition());
    }
}
