/*
 * Copyright (C) 2020 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.compiler.processing

import androidx.room.compiler.processing.javac.JavacProcessingEnv
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.squareup.javapoet.ArrayTypeName
import com.squareup.javapoet.TypeName
import javax.annotation.processing.ProcessingEnvironment
import kotlin.reflect.KClass

/**
 * API for a Processor that is either backed by Java's Annotation Processing API or KSP.
 */
@ExperimentalProcessingApi
interface XProcessingEnv {

    val backend: Backend

    /**
     * The logger interface to log messages
     */
    val messager: XMessager

    /**
     * List of options passed into the annotation processor
     */
    val options: Map<String, String>

    /**
     * The API to generate files
     */
    val filer: XFiler

    /**
     * Configuration to control certain behaviors of XProcessingEnv.
     */
    val config: XProcessingEnvConfig

    /**
     * Java language version of the processing environment.
     *
     * Value is the common JDK version representation even for the older JVM Specs named using the
     * 1.x notation. i.e. for '1.8' this return 8, for '11' this returns 11, etc.
     */
    val jvmVersion: Int

    /**
     * Looks for the [XTypeElement] with the given qualified name and returns `null` if it does not
     * exist.
     */
    fun findTypeElement(qName: String): XTypeElement?

    /**
     * Looks for the [XType] with the given qualified name and returns `null` if it does not exist.
     */
    fun findType(qName: String): XType?

    /**
     * Returns the [XType] with the given qualified name or throws an exception if it does not
     * exist.
     */
    fun requireType(qName: String): XType = checkNotNull(findType(qName)) {
        "cannot find required type $qName"
    }

    /**
     * Returns the [XTypeElement] for the annotation that should be added to the generated code.
     */
    fun findGeneratedAnnotation(): XTypeElement?

    /**
     * Returns an [XType] for the given [type] element with the type arguments specified
     * as in [types].
     */
    fun getDeclaredType(type: XTypeElement, vararg types: XType): XType

    /**
     * Return an [XArrayType] that has [type] as the [XArrayType.componentType].
     */
    fun getArrayType(type: XType): XArrayType

    /**
     * Returns the [XTypeElement] with the given qualified name or throws an exception if it does
     * not exist.
     */
    fun requireTypeElement(qName: String): XTypeElement {
        return checkNotNull(findTypeElement(qName)) {
            "Cannot find required type element $qName"
        }
    }

    // helpers for smooth migration, these could be extension methods
    fun requireType(typeName: TypeName) = checkNotNull(findType(typeName)) {
        "cannot find required type $typeName"
    }

    fun requireType(klass: KClass<*>) = requireType(klass.java.canonicalName!!)

    fun findType(typeName: TypeName): XType? {
        // TODO we probably need more complicated logic here but right now room only has these
        //  usages.
        if (typeName is ArrayTypeName) {
            return findType(typeName.componentType)?.let {
                getArrayType(it)
            }
        }
        return findType(typeName.toString())
    }

    fun findType(klass: KClass<*>) = findType(klass.java.canonicalName!!)

    fun requireTypeElement(typeName: TypeName) = requireTypeElement(typeName.toString())

    fun requireTypeElement(klass: KClass<*>) = requireTypeElement(klass.java.canonicalName!!)

    fun findTypeElement(typeName: TypeName) = findTypeElement(typeName.toString())

    fun findTypeElement(klass: KClass<*>) = findTypeElement(klass.java.canonicalName!!)

    fun getArrayType(typeName: TypeName) = getArrayType(requireType(typeName))

    enum class Backend {
        JAVAC,
        KSP
    }

    companion object {
        /**
         * Creates a new [XProcessingEnv] implementation derived from the given Java [env].
         */
        @JvmStatic
        @JvmOverloads
        fun create(
            env: ProcessingEnvironment,
            config: XProcessingEnvConfig = XProcessingEnvConfig.DEFAULT
        ): XProcessingEnv = JavacProcessingEnv(env, config)

        /**
         * Creates a new [XProcessingEnv] implementation derived from the given KSP environment.
         */
        @JvmStatic
        @JvmOverloads
        fun create(
            options: Map<String, String>,
            resolver: Resolver,
            codeGenerator: CodeGenerator,
            logger: KSPLogger,
            config: XProcessingEnvConfig = XProcessingEnvConfig.DEFAULT
        ): XProcessingEnv = KspProcessingEnv(
            options = options,
            codeGenerator = codeGenerator,
            logger = logger,
            config = config
        ).also { it.resolver = resolver }
    }

    /**
     * Returns [XTypeElement]s with the given package name. Note that this call can be expensive.
     *
     * @param packageName the package name to look up.
     *
     * @return A list of [XTypeElement] with matching package name. This will return declarations
     * from both dependencies and source. If the package is not found an empty list will be
     * returned.
     */
    fun getTypeElementsFromPackage(packageName: String): List<XTypeElement>

    // TODO: Add support for getting top level members in a package
}
