/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.room.processor

import androidx.room.Entity
import androidx.room.parser.Collate
import androidx.room.parser.SQLTypeAffinity
import androidx.room.compiler.processing.XVariableElement
import androidx.room.solver.types.ColumnTypeAdapter
import androidx.room.testing.TestInvocation
import androidx.room.testing.TestProcessor
import androidx.room.vo.Field
import com.google.common.truth.Truth
import com.google.testing.compile.CompileTester
import com.google.testing.compile.JavaFileObjects
import com.google.testing.compile.JavaSourcesSubjectFactory
import com.squareup.javapoet.TypeName
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.nullValue
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import simpleRun
import java.util.Locale

@Suppress("HasPlatformType")
@RunWith(JUnit4::class)
class FieldProcessorTest {
    companion object {
        const val ENTITY_PREFIX = """
                package foo.bar;
                import androidx.room.*;
                import androidx.annotation.NonNull;
                @Entity
                abstract class MyEntity {
                """
        const val ENTITY_SUFFIX = "}"
        val ALL_PRIMITIVES = arrayListOf(
            TypeName.INT,
            TypeName.BYTE,
            TypeName.SHORT,
            TypeName.LONG,
            TypeName.CHAR,
            TypeName.FLOAT,
            TypeName.DOUBLE
        )
        val ARRAY_CONVERTER = JavaFileObjects.forSourceLines("foo.bar.MyConverter",
                """
                package foo.bar;
                import androidx.room.*;
                public class MyConverter {
                ${ALL_PRIMITIVES.joinToString("\n") {
                    val arrayDef = "$it[]"
                    "@TypeConverter public static String" +
                            " arrayIntoString($arrayDef input) { return null;}" +
                            "@TypeConverter public static $arrayDef" +
                            " stringIntoArray$it(String input) { return null;}"
                }}
                ${ALL_PRIMITIVES.joinToString("\n") {
                    val arrayDef = "${it.box()}[]"
                    "@TypeConverter public static String" +
                            " arrayIntoString($arrayDef input) { return null;}" +
                            "@TypeConverter public static $arrayDef" +
                            " stringIntoArray${it}Boxed(String input) { return null;}"
                }}
                }
                """)

        private fun TypeName.affinity(): SQLTypeAffinity {
            return when (this) {
                TypeName.FLOAT, TypeName.DOUBLE -> SQLTypeAffinity.REAL
                else -> SQLTypeAffinity.INTEGER
            }
        }

        private fun TypeName.box(invocation: TestInvocation) =
            typeMirror(invocation).boxed()

        private fun TypeName.typeMirror(invocation: TestInvocation) =
            invocation.processingEnv.requireType(this)
    }

    @Test
    fun primitives() {
        ALL_PRIMITIVES.forEach { primitive ->
            singleEntity("$primitive x;") { field, invocation ->
                assertThat(field, `is`(
                        Field(name = "x",
                                type = primitive.typeMirror(invocation),
                                element = field.element,
                                affinity = primitive.affinity()
                        )))
            }.compilesWithoutError()
        }
    }

    @Test
    fun boxed() {
        ALL_PRIMITIVES.forEach { primitive ->
            singleEntity("${primitive.box()} y;") { field, invocation ->
                assertThat(field, `is`(
                        Field(name = "y",
                                type = primitive.box(invocation),
                                element = field.element,
                                affinity = primitive.affinity())))
            }.compilesWithoutError()
        }
    }

    @Test
    fun columnName() {
        singleEntity("""
            @ColumnInfo(name = "foo")
            @PrimaryKey
            int x;
            """) { field, invocation ->
            assertThat(field, `is`(
                    Field(name = "x",
                            type = TypeName.INT.typeMirror(invocation),
                            element = field.element,
                            columnName = "foo",
                            affinity = SQLTypeAffinity.INTEGER)))
        }.compilesWithoutError()
    }

    @Test
    fun indexed() {
        singleEntity("""
            @ColumnInfo(name = "foo", index = true)
            int x;
            """) { field, invocation ->
            assertThat(field, `is`(
                    Field(name = "x",
                            type = TypeName.INT.typeMirror(invocation),
                            element = field.element,
                            columnName = "foo",
                            affinity = SQLTypeAffinity.INTEGER,
                            indexed = true)))
        }.compilesWithoutError()
    }

    @Test
    fun emptyColumnName() {
        singleEntity("""
            @ColumnInfo(name = "")
            int x;
            """) { _, _ ->
        }.failsToCompile().withErrorContaining(ProcessorErrors.COLUMN_NAME_CANNOT_BE_EMPTY)
    }

    @Test
    fun byteArrayWithEnforcedType() {
        singleEntity("@TypeConverters(foo.bar.MyConverter.class)" +
                "@ColumnInfo(typeAffinity = ColumnInfo.TEXT) byte[] arr;") { field, invocation ->
            assertThat(field, `is`(Field(name = "arr",
                    type = invocation.processingEnv.getArrayType(TypeName.BYTE),
                    element = field.element,
                    affinity = SQLTypeAffinity.TEXT)))
            assertThat((field.cursorValueReader as? ColumnTypeAdapter)?.typeAffinity,
                    `is`(SQLTypeAffinity.TEXT))
        }.compilesWithoutError()
    }

    @Test
    fun primitiveArray() {
        ALL_PRIMITIVES.forEach { primitive ->
            singleEntity("@TypeConverters(foo.bar.MyConverter.class) " +
                    "${primitive.toString().toLowerCase(Locale.US)}[] arr;") { field, invocation ->
                assertThat(field, `is`(
                        Field(name = "arr",
                                type = invocation.processingEnv.getArrayType(primitive),
                                element = field.element,
                                affinity = if (primitive == TypeName.BYTE) {
                                    SQLTypeAffinity.BLOB
                                } else {
                                    SQLTypeAffinity.TEXT
                                })))
            }.compilesWithoutError()
        }
    }

    @Test
    fun boxedArray() {
        ALL_PRIMITIVES.forEach { primitive ->
            singleEntity("@TypeConverters(foo.bar.MyConverter.class) " +
                    "${primitive.box()}[] arr;") { field, invocation ->
                assertThat(field, `is`(
                        Field(name = "arr",
                                type = invocation.processingEnv.getArrayType(
                                        primitive.box()),
                                element = field.element,
                                affinity = SQLTypeAffinity.TEXT)))
            }.compilesWithoutError()
        }
    }

    @Test
    fun generic() {
        singleEntity("""
                static class BaseClass<T> {
                    T item;
                }
                @Entity
                static class Extending extends BaseClass<java.lang.Integer> {
                }
                """) { field, invocation ->
            assertThat(field, `is`(Field(name = "item",
                    type = TypeName.INT.box(invocation),
                    element = field.element,
                    affinity = SQLTypeAffinity.INTEGER)))
        }.compilesWithoutError()
    }

    @Test
    fun unboundGeneric() {
        singleEntity("""
                @Entity
                static class BaseClass<T> {
                    T item;
                }
                """) { _, _ -> }.failsToCompile()
                .withErrorContaining(ProcessorErrors.CANNOT_USE_UNBOUND_GENERICS_IN_ENTITY_FIELDS)
    }

    @Test
    fun nameVariations() {
        simpleRun {
            val variableElement = mock(XVariableElement::class.java)
            assertThat(Field(variableElement, "x", TypeName.INT.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("x")))
            assertThat(Field(variableElement, "x", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("x")))
            assertThat(Field(variableElement, "xAll",
                TypeName.BOOLEAN.typeMirror(it), SQLTypeAffinity.INTEGER)
                    .nameWithVariations, `is`(arrayListOf("xAll")))
        }
    }

    @Test
    fun nameVariations_is() {
        val elm = mock(XVariableElement::class.java)
        simpleRun {
            assertThat(Field(elm, "isX", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("isX", "x")))
            assertThat(Field(elm, "isX", TypeName.INT.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("isX")))
            assertThat(Field(elm, "is", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("is")))
            assertThat(Field(elm, "isAllItems", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations,
                    `is`(arrayListOf("isAllItems", "allItems")))
        }
    }

    @Test
    fun nameVariations_has() {
        val elm = mock(XVariableElement::class.java)
        simpleRun {
            assertThat(Field(elm, "hasX", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("hasX", "x")))
            assertThat(Field(elm, "hasX", TypeName.INT.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("hasX")))
            assertThat(Field(elm, "has", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("has")))
            assertThat(Field(elm, "hasAllItems", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations,
                    `is`(arrayListOf("hasAllItems", "allItems")))
        }
    }

    @Test
    fun nameVariations_m() {
        val elm = mock(XVariableElement::class.java)
        simpleRun {
            assertThat(Field(elm, "mall", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("mall")))
            assertThat(Field(elm, "mallVars", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("mallVars")))
            assertThat(Field(elm, "mAll", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("mAll", "all")))
            assertThat(Field(elm, "m", TypeName.INT.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("m")))
            assertThat(Field(elm, "mallItems", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations,
                    `is`(arrayListOf("mallItems")))
            assertThat(Field(elm, "mAllItems", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations,
                    `is`(arrayListOf("mAllItems", "allItems")))
        }
    }

    @Test
    fun nameVariations_underscore() {
        val elm = mock(XVariableElement::class.java)
        simpleRun {
            assertThat(Field(elm, "_all", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("_all", "all")))
            assertThat(Field(elm, "_", TypeName.INT.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("_")))
            assertThat(Field(elm, "_allItems", TypeName.BOOLEAN.typeMirror(it),
                    SQLTypeAffinity.INTEGER).nameWithVariations,
                    `is`(arrayListOf("_allItems", "allItems")))
        }
    }

    @Test
    fun collate() {
        Collate.values().forEach { collate ->
            singleEntity("""
            @PrimaryKey
            @ColumnInfo(collate = ColumnInfo.${collate.name})
            String code;
            """) { field, invocation ->
                assertThat(field, `is`(
                        Field(name = "code",
                                type = invocation.context.COMMON_TYPES.STRING,
                                element = field.element,
                                columnName = "code",
                                collate = collate,
                                affinity = SQLTypeAffinity.TEXT)))
            }.compilesWithoutError()
        }
    }

    @Test
    fun defaultValues_number() {
        testDefaultValue("\"1\"", "int") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("1")))
        }.compilesWithoutError()
        testDefaultValue("\"\"", "int") { defaultValue ->
            assertThat(defaultValue, `is`(nullValue()))
        }.compilesWithoutError()
        testDefaultValue("\"null\"", "Integer") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("null")))
        }.compilesWithoutError()
        testDefaultValue("ColumnInfo.VALUE_UNSPECIFIED", "int") { defaultValue ->
            assertThat(defaultValue, `is`(nullValue()))
        }.compilesWithoutError()
        testDefaultValue("\"CURRENT_TIMESTAMP\"", "long") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("CURRENT_TIMESTAMP")))
        }.compilesWithoutError()
        testDefaultValue("\"true\"", "boolean") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("true")))
        }.compilesWithoutError()
        testDefaultValue("\"false\"", "boolean") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("false")))
        }.compilesWithoutError()
    }

    @Test
    fun defaultValues_nonNull() {
        testDefaultValue("\"null\"", "int") {
        }.failsToCompile().withErrorContaining(ProcessorErrors.DEFAULT_VALUE_NULLABILITY)
        testDefaultValue("\"null\"", "@NonNull String") {
        }.failsToCompile().withErrorContaining(ProcessorErrors.DEFAULT_VALUE_NULLABILITY)
    }

    @Test
    fun defaultValues_text() {
        testDefaultValue("\"a\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("'a'")))
        }.compilesWithoutError()
        testDefaultValue("\"'a'\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("'a'")))
        }.compilesWithoutError()
        testDefaultValue("\"\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("''")))
        }.compilesWithoutError()
        testDefaultValue("\"null\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("null")))
        }.compilesWithoutError()
        testDefaultValue("ColumnInfo.VALUE_UNSPECIFIED", "String") { defaultValue ->
            assertThat(defaultValue, `is`(nullValue()))
        }.compilesWithoutError()
        testDefaultValue("\"CURRENT_TIMESTAMP\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("CURRENT_TIMESTAMP")))
        }.compilesWithoutError()
        testDefaultValue("\"('Created at ' || CURRENT_TIMESTAMP)\"", "String") { defaultValue ->
            assertThat(defaultValue, `is`(equalTo("('Created at ' || CURRENT_TIMESTAMP)")))
        }.compilesWithoutError()
    }

    private fun testDefaultValue(
        defaultValue: String,
        fieldType: String,
        body: (String?) -> Unit
    ): CompileTester {
        return singleEntity(
            """
                @ColumnInfo(defaultValue = $defaultValue)
                $fieldType name;
            """
        ) { field, _ ->
            body(field.defaultValue)
        }
    }

    fun singleEntity(vararg input: String, handler: (Field, invocation: TestInvocation) -> Unit):
            CompileTester {
        return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
                .that(listOf(JavaFileObjects.forSourceString("foo.bar.MyEntity",
                        ENTITY_PREFIX + input.joinToString("\n") + ENTITY_SUFFIX
                ), ARRAY_CONVERTER))
                .processedWith(TestProcessor.builder()
                        .forAnnotations(androidx.room.Entity::class)
                        .nextRunHandler { invocation ->
                            val (owner, fieldElement) = invocation.roundEnv
                                    .getElementsAnnotatedWith(Entity::class.java)
                                    .map {
                                        Pair(it, it.asTypeElement()
                                            .getAllFieldsIncludingPrivateSupers().firstOrNull())
                                    }
                                    .first { it.second != null }
                            val entityContext =
                                    TableEntityProcessor(
                                            baseContext = invocation.context,
                                            element = owner.asTypeElement()
                                    ).context
                            val parser = FieldProcessor(
                                    baseContext = entityContext,
                                    containing = owner.asDeclaredType(),
                                    element = fieldElement!!.asVariableElement(),
                                    bindingScope = FieldProcessor.BindingScope.TWO_WAY,
                                    fieldParent = null,
                                    onBindingError = { field, errorMsg ->
                                        invocation.context.logger.e(field.element, errorMsg) }
                                    )
                            handler(parser.process(), invocation)
                            true
                        }
                        .build())
    }
}
