package com.fasterxml.jackson.databind.deser;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;

public class PropertyAliasTest extends BaseMapTest
{
    static class AliasBean {
        @JsonAlias({ "nm", "Name" })
        public String name;

        int _xyz;

        int _a;

        @JsonCreator
        public AliasBean(@JsonProperty("a")
            @JsonAlias("A") int a) {
            _a = a;
        }
        
        @JsonAlias({ "Xyz" })
        public void setXyz(int x) {
            _xyz = x;
        }
    }

    static class AliasBean2378 {
        String partitionId;
        String _id;

        private AliasBean2378(boolean bogus, String partId, String userId) {
            partitionId = partId;
            _id = userId;
        }

        @JsonCreator
        public static AliasBean2378 create(@JsonProperty("partitionId") String partId,
                @JsonProperty("id") @JsonAlias("userId") String userId) {
            return new AliasBean2378(false, partId, userId);
        }
    }

    static class PolyWrapperForAlias {
        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
                include = JsonTypeInfo.As.WRAPPER_ARRAY)
        @JsonSubTypes({
            @JsonSubTypes.Type(value = AliasBean.class,name = "ab"),
        })
        public Object value;

        protected PolyWrapperForAlias() { }
        public PolyWrapperForAlias(Object v) { value = v; }
    }

    private final ObjectMapper MAPPER = newJsonMapper();

    // [databind#1029]
    public void testSimpleAliases() throws Exception
    {
        AliasBean bean;

        // first, one indicated by field annotation, set via field
        bean = MAPPER.readValue(aposToQuotes("{'Name':'Foobar','a':3,'xyz':37}"),
                AliasBean.class);
        assertEquals("Foobar", bean.name);
        assertEquals(3, bean._a);
        assertEquals(37, bean._xyz);

        // then method-bound one
        bean = MAPPER.readValue(aposToQuotes("{'name':'Foobar','a':3,'Xyz':37}"),
                AliasBean.class);
        assertEquals("Foobar", bean.name);
        assertEquals(3, bean._a);
        assertEquals(37, bean._xyz);
        
        // and finally, constructor-backed one
        bean = MAPPER.readValue(aposToQuotes("{'name':'Foobar','A':3,'xyz':37}"),
                AliasBean.class);
        assertEquals("Foobar", bean.name);
        assertEquals(3, bean._a);
        assertEquals(37, bean._xyz);
    }

    public void testAliasWithPolymorphic() throws Exception
    {
        PolyWrapperForAlias value = MAPPER.readValue(aposToQuotes(
                "{'value': ['ab', {'nm' : 'Bob', 'A' : 17} ] }"
                ), PolyWrapperForAlias.class);
        assertNotNull(value.value);
        AliasBean bean = (AliasBean) value.value;
        assertEquals("Bob", bean.name);
        assertEquals(17, bean._a);
    }

    // [databind#2378]
    public void testAliasInFactoryMethod() throws Exception
    {
        AliasBean2378 bean = MAPPER.readValue(aposToQuotes(
                "{'partitionId' : 'a', 'userId' : '123'}"
                ), AliasBean2378.class);
        assertEquals("a", bean.partitionId);
        assertEquals("123", bean._id);
    }
}

@@ -395,22 +395,130 @@
 atabind.
-Object
+MapperFeature;%0Aimport com.fasterxml.jackson.databind.ObjectMapper;%0Aimport com.fasterxml.jackson.databind.json.Json
 Mapper;%0A
@@ -1825,24 +1825,490 @@
 v; %7D%0A    %7D%0A%0A
+    // %5Bdatabind#2669%5D%0A    static class Pojo2669 %7B%0A        @JsonAlias(%7B%22nick%22, %22name%22%7D)%0A        private String name;%0A%0A        public String getName() %7B%0A            return name;%0A        %7D%0A%0A        public void setName(String name) %7B%0A            this.name = name;%0A        %7D%0A    %7D%0A%0A    /*%0A    /**********************************************************************%0A    /* Test methods%0A    /**********************************************************************%0A     */%0A%0A
     private 
@@ -4015,24 +4015,24 @@
 rtitionId);%0A
-
         asse
@@ -4063,11 +4063,442 @@
 );%0A    %7D
+%0A%0A    // %5Bdatabind#2669%5D%0A    public void testCaseInsensitiveAliases() throws Exception %7B%0A%0A        ObjectMapper mapper = JsonMapper.builder()%0A                .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)%0A                .build();%0A%0A        String text = %22%7B%5C%22name%5C%22:%5C%22test%5C%22%7D%22;%0A        Pojo2669 pojo = mapper.readValue(text, Pojo2669.class);%0A        assertNotNull(pojo);%0A        assertEquals(%22test%22, pojo.getName());%0A    %7D
 %0A%7D%0A

Add a (passing) test for #2669