/*
 * 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.
 */

import androidx.room.DatabaseView
import androidx.room.Entity
import androidx.room.ext.GuavaUtilConcurrentTypeNames
import androidx.room.ext.KotlinTypeNames
import androidx.room.ext.LifecyclesTypeNames
import androidx.room.ext.PagingTypeNames
import androidx.room.ext.ReactiveStreamsTypeNames
import androidx.room.ext.RoomGuavaTypeNames
import androidx.room.ext.RoomRxJava2TypeNames
import androidx.room.ext.RoomRxJava3TypeNames
import androidx.room.ext.RxJava2TypeNames
import androidx.room.ext.RxJava3TypeNames
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XVariableElement
import androidx.room.processor.DatabaseViewProcessor
import androidx.room.processor.TableEntityProcessor
import androidx.room.solver.CodeGenScope
import androidx.room.testing.TestInvocation
import androidx.room.testing.TestProcessor
import androidx.room.verifier.DatabaseVerifier
import androidx.room.writer.ClassWriter
import com.google.common.io.Files
import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
import com.google.testing.compile.CompileTester
import com.google.testing.compile.JavaFileObjects
import com.google.testing.compile.JavaSourcesSubjectFactory
import com.squareup.javapoet.ClassName
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import java.io.File
import java.nio.charset.StandardCharsets.UTF_8
import java.util.Locale
import javax.tools.JavaFileObject
import javax.tools.StandardLocation
import javax.tools.ToolProvider.getSystemJavaCompiler

object COMMON {
    val USER by lazy {
        loadJavaCode("common/input/User.java", "foo.bar.User")
    }
    val USER_SUMMARY by lazy {
        loadJavaCode("common/input/UserSummary.java", "foo.bar.UserSummary")
    }
    val USER_TYPE_NAME by lazy {
        ClassName.get("foo.bar", "User")
    }
    val BOOK by lazy {
        loadJavaCode("common/input/Book.java", "foo.bar.Book")
    }
    val NOT_AN_ENTITY by lazy {
        loadJavaCode("common/input/NotAnEntity.java", "foo.bar.NotAnEntity")
    }

    val PARENT by lazy {
        loadJavaCode("common/input/Parent.java", "foo.bar.Parent")
    }
    val CHILD1 by lazy {
        loadJavaCode("common/input/Child1.java", "foo.bar.Child1")
    }
    val CHILD2 by lazy {
        loadJavaCode("common/input/Child2.java", "foo.bar.Child2")
    }
    val INFO by lazy {
        loadJavaCode("common/input/Info.java", "foo.bar.Info")
    }

    val NOT_AN_ENTITY_TYPE_NAME by lazy {
        ClassName.get("foo.bar", "NotAnEntity")
    }

    val MULTI_PKEY_ENTITY by lazy {
        loadJavaCode("common/input/MultiPKeyEntity.java", "MultiPKeyEntity")
    }
    val LIVE_DATA by lazy {
        loadJavaCode("common/input/LiveData.java", LifecyclesTypeNames.LIVE_DATA.toString())
    }
    val COMPUTABLE_LIVE_DATA by lazy {
        loadJavaCode("common/input/ComputableLiveData.java",
                LifecyclesTypeNames.COMPUTABLE_LIVE_DATA.toString())
    }
    val PUBLISHER by lazy {
        loadJavaCode("common/input/reactivestreams/Publisher.java",
                ReactiveStreamsTypeNames.PUBLISHER.toString())
    }
    val RX2_FLOWABLE by lazy {
        loadJavaCode("common/input/rxjava2/Flowable.java",
                RxJava2TypeNames.FLOWABLE.toString())
    }
    val RX2_OBSERVABLE by lazy {
        loadJavaCode("common/input/rxjava2/Observable.java",
                RxJava2TypeNames.OBSERVABLE.toString())
    }
    val RX2_SINGLE by lazy {
        loadJavaCode("common/input/rxjava2/Single.java",
                RxJava2TypeNames.SINGLE.toString())
    }
    val RX2_MAYBE by lazy {
        loadJavaCode("common/input/rxjava2/Maybe.java",
                RxJava2TypeNames.MAYBE.toString())
    }
    val RX2_COMPLETABLE by lazy {
        loadJavaCode("common/input/rxjava2/Completable.java",
                RxJava2TypeNames.COMPLETABLE.toString())
    }

    val RX2_ROOM by lazy {
        loadJavaCode("common/input/Rx2Room.java", RoomRxJava2TypeNames.RX_ROOM.toString())
    }

    val RX3_FLOWABLE by lazy {
        loadJavaCode("common/input/rxjava3/Flowable.java",
            RxJava3TypeNames.FLOWABLE.toString())
    }
    val RX3_OBSERVABLE by lazy {
        loadJavaCode("common/input/rxjava3/Observable.java",
            RxJava3TypeNames.OBSERVABLE.toString())
    }
    val RX3_SINGLE by lazy {
        loadJavaCode("common/input/rxjava3/Single.java",
            RxJava3TypeNames.SINGLE.toString())
    }
    val RX3_MAYBE by lazy {
        loadJavaCode("common/input/rxjava3/Maybe.java",
            RxJava3TypeNames.MAYBE.toString())
    }
    val RX3_COMPLETABLE by lazy {
        loadJavaCode("common/input/rxjava3/Completable.java",
            RxJava3TypeNames.COMPLETABLE.toString())
    }

    val RX3_ROOM by lazy {
        loadJavaCode("common/input/Rx3Room.java", RoomRxJava3TypeNames.RX_ROOM.toString())
    }

    val DATA_SOURCE_FACTORY by lazy {
        loadJavaCode("common/input/DataSource.java", "androidx.paging.DataSource")
    }

    val POSITIONAL_DATA_SOURCE by lazy {
        loadJavaCode("common/input/PositionalDataSource.java",
                PagingTypeNames.POSITIONAL_DATA_SOURCE.toString())
    }

    val LISTENABLE_FUTURE by lazy {
        loadJavaCode("common/input/guava/ListenableFuture.java",
            GuavaUtilConcurrentTypeNames.LISTENABLE_FUTURE.toString())
    }

    val GUAVA_ROOM by lazy {
        loadJavaCode("common/input/GuavaRoom.java",
            RoomGuavaTypeNames.GUAVA_ROOM.toString())
    }

    val CHANNEL by lazy {
        loadJavaCode("common/input/coroutines/Channel.java",
            KotlinTypeNames.CHANNEL.toString())
    }

    val SEND_CHANNEL by lazy {
        loadJavaCode("common/input/coroutines/SendChannel.java",
            KotlinTypeNames.SEND_CHANNEL.toString())
    }

    val RECEIVE_CHANNEL by lazy {
        loadJavaCode("common/input/coroutines/ReceiveChannel.java",
            KotlinTypeNames.RECEIVE_CHANNEL.toString())
    }
}
fun testCodeGenScope(): CodeGenScope {
    return CodeGenScope(mock(ClassWriter::class.java))
}

fun simpleRun(
    vararg jfos: JavaFileObject,
    classpathFiles: Set<File> = emptySet(),
    options: List<String> = emptyList(),
    f: (TestInvocation) -> Unit
): CompileTester {
    return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
            .that(jfos.toList() + JavaFileObjects.forSourceLines("NoOp", "final class NoOp {}"))
            .apply {
                if (classpathFiles.isNotEmpty()) {
                    withClasspath(classpathFiles)
                }
            }
            .withCompilerOptions(options)
            .processedWith(TestProcessor.builder()
                    .nextRunHandler {
                        f(it)
                        true
                    }
                    .forAnnotations("*")
                    .build())
}

fun loadJavaCode(fileName: String, qName: String): JavaFileObject {
    val contents = File("src/test/data/$fileName").readText(Charsets.UTF_8)
    return JavaFileObjects.forSourceString(qName, contents)
}

fun createVerifierFromEntitiesAndViews(invocation: TestInvocation): DatabaseVerifier {
    return DatabaseVerifier.create(invocation.context, mock(XElement::class.java),
            invocation.getEntities(), invocation.getViews())!!
}

fun TestInvocation.getViews(): List<androidx.room.vo.DatabaseView> {
    return roundEnv.getElementsAnnotatedWith(DatabaseView::class.java).map {
        DatabaseViewProcessor(context, it.asTypeElement()).process()
    }
}

fun TestInvocation.getEntities(): List<androidx.room.vo.Entity> {
    val entities = roundEnv.getElementsAnnotatedWith(Entity::class.java).map {
        TableEntityProcessor(context, it.asTypeElement()).process()
    }
    return entities
}

/**
 * Create mocks of [XElement] and [XType] so that they can be used for instantiating a fake
 * [androidx.room.vo.Field].
 */
fun mockElementAndType(): Pair<XVariableElement, XType> {
    val element = mock(XVariableElement::class.java)
    val type = mock(XType::class.java)
    doReturn(type).`when`(element).type
    return element to type
}

fun compileLibrarySource(sourceName: String, code: String): Set<File> {
    val sourceCode = """
        package test.library;
        import androidx.room.*;
        $code
        """
    return compileLibrarySources(JavaFileObjects.forSourceString(sourceName, sourceCode))
}

/**
 * Compiles an array of sources and returns a set of files to be used as classpath pointing
 * to the .class files generated by the compilation. This method is useful for creating an
 * environment where the annotation processor has to process compiled classes from a library.
 */
fun compileLibrarySources(vararg sources: JavaFileObject): Set<File> {
    val lib = Files.createTempDir()
    val compiler = getSystemJavaCompiler()
    val fileManager = compiler.getStandardFileManager(null, Locale.getDefault(), UTF_8)
    fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(lib))
    val task = compiler.getTask(null, fileManager, null, emptyList(), null, listOf(*sources))
    assertThat(task.call()).isTrue()
    return getSystemClasspathFiles() + lib
}

private fun getSystemClasspathFiles(): Set<File> {
    val pathSeparator = System.getProperty("path.separator")!!
    return System.getProperty("java.class.path")!!.split(pathSeparator).map { File(it) }.toSet()
}

fun String.toJFO(qName: String): JavaFileObject = JavaFileObjects.forSourceLines(qName, this)