package com.fasterxml.jackson.databind.deser.creators.broken;

import java.util.Arrays;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;

// Test(s) to check for handling of Static Factory Creator bindings
// which up until 2.11.2 used type variable bindings of the surrounding
// class for Static methods too. This is semantically wrong, but quite a
// bit of usage existed -- but no one had contributed tests to verify
// this as expected behavior.
// When this usage broken in 2.11.3 -- it was never actually supported but
// happened to sort of work -- reports came in. This test verifies
// assumed behavior so that previous broken (but useful) bindings could
// be brought back for 2.11.4.
//
// Work for 2.12 should find better solution than this.

public class Pre212StaticFactoryImplicitBindingTest extends BaseMapTest
{
    // [databind#2894]
    static class Wrapper<T> {
        List<T> values;

        protected Wrapper(List<T> v) {
            values = v;
        }

        public List<T> getValue() { return values; }

        @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
        static <T> Wrapper<T> fromValues(@JsonProperty("value") List<T> values) {
          return new Wrapper<T>(values);
        }
    }

    static class Value {
        public int x;

        protected Value() { }
        protected Value(int x0) { x = x0; }

        @Override
        public boolean equals(Object o) {
            return (o instanceof Value) && ((Value) o).x == x;
        }

        @Override
        public String toString() {
            return "[Value x="+x+"]";
        }
    }

    private final ObjectMapper MAPPER = newJsonMapper();

    public void testIssue2894() throws Exception
    {
        Wrapper<Value> src = new Wrapper<>(Arrays.asList(new Value(1), new Value(2)));
        final String json = MAPPER.writeValueAsString(src);
        Wrapper<Value> output = MAPPER.readValue(json,
                new TypeReference<Wrapper<Value>>() {});
        assertEquals(src.values, output.values);
    }
}

@@ -212,16 +212,17 @@
 operty;%0A
+%0A
 import c
@@ -267,16 +267,17 @@
 erence;%0A
+%0A
 import c
@@ -1766,24 +1766,917 @@
    %7D%0A    %7D%0A%0A
+    // %5Bdatabind#2895%5D%0A    static class SimpleWrapper2895%3CT%3E %7B%0A        final T value;%0A%0A        SimpleWrapper2895(T value) %7B%0A            this.value = value;%0A        %7D%0A%0A        @JsonCreator(mode = JsonCreator.Mode.DELEGATING)%0A        public static %3CT%3E SimpleWrapper2895%3CT%3E fromJson(JsonSimpleWrapper2895%3CT%3E value) %7B%0A            return new SimpleWrapper2895%3C%3E(value.object);%0A        %7D%0A    %7D%0A%0A    static final class JsonSimpleWrapper2895%3CT%3E %7B%0A        @JsonProperty(%22object%22)%0A        public T object;%0A    %7D%0A%0A    static class Account2895 %7B%0A        private long id;        %0A        private String name;%0A%0A        @JsonCreator%0A        public Account2895(@JsonProperty(%22name%22) String name,%0A                @JsonProperty(%22id%22) long id) %7B%0A            this.id = id;%0A            this.name = name;%0A        %7D%0A%0A        public String getName() %7B return name; %7D%0A        public long getId() %7B return id; %7D%0A    %7D%0A%0A
     private 
@@ -2721,16 +2721,39 @@
 per();%0A%0A
+    // %5Bdatabind#2894%5D%0A
     publ
@@ -3058,16 +3058,16 @@
 () %7B%7D);%0A
-
         
@@ -3112,11 +3112,463 @@
 );%0A    %7D
+%0A%0A    // %5Bdatabind#2895%5D%0A    public void testIssue2895() throws Exception%0A    %7B%0A        SimpleWrapper2895%3CAccount2895%3E wrapper = MAPPER%0A                .readerFor(new TypeReference%3CSimpleWrapper2895%3CAccount2895%3E%3E() %7B%7D)%0A                .readValue(%22%7B%5C%22object%5C%22:%7B%5C%22id%5C%22:1,%5C%22name%5C%22:%5C%22name1%5C%22%7D%7D%22);%0A                %0A        Account2895 account = wrapper.value;%0A        assertEquals(1, account.getId());%0A        assertEquals(%22name1%22, account.getName());%0A    %7D
 %0A%7D%0A

Add test from #2895