/*
 * Copyright 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 com.google.devsite.renderer.converters

import com.google.devsite.renderer.Language
import org.jetbrains.dokka.base.transformers.documentables.isException
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.DAnnotation
import org.jetbrains.dokka.model.DClass
import org.jetbrains.dokka.model.DClasslike
import org.jetbrains.dokka.model.DEnum
import org.jetbrains.dokka.model.DFunction
import org.jetbrains.dokka.model.DInterface
import org.jetbrains.dokka.model.DObject
import org.jetbrains.dokka.model.DProperty
import org.jetbrains.dokka.model.Documentable
import org.jetbrains.dokka.model.ExtraModifiers
import org.jetbrains.dokka.model.Nullable
import org.jetbrains.dokka.model.Projection
import org.jetbrains.dokka.model.Variance
import org.jetbrains.dokka.model.WithChildren
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.model.toAdditionalModifiers

/** Recursively expands all children. */
internal val <T> WithChildren<T>.explodedChildren: List<T>
    get() = children + children.filterIsInstance<WithChildren<T>>().flatMap { it.explodedChildren }

/**
 * Returns the type's name. Do not use [Documentable.name] as it won't include the outer class.
 */
internal fun DClasslike.name() = dri.classNames!!

internal fun DClasslike.packageName() = dri.packageName!!

private val baseClasses = listOf("kotlin.Any", "java.lang.Object", "kotlin.Enum",
    "java.lang.Enum", "java.lang.annotation.Annotation")
/**
 * Returns true if this dri is from a build in base class like Any, Object, Enum, Annotation
 */
internal fun DRI.isFromBaseClass(): Boolean {
    val classAndPackage = packageName?.plus(".").plus(classNames)
    return baseClasses.contains(classAndPackage)
}

/** @return true if this is a nullable type, false otherwise */
internal fun Projection.isNullable(): Boolean = when (this) {
    is Nullable -> true
    is Variance<*> -> inner.isNullable()
    else -> false
}

/**
 * @param displayLanguage the Language of the docs this Documentable will be displayed in
 * @return the String name that represents this type when displayed
 */
fun Documentable.stringForType(displayLanguage: Language): String = when (this) {
    is DClass -> "class"
    is DInterface -> "interface"
    is DEnum -> "enum"
    is DAnnotation -> "annotation"
    is DFunction -> when (displayLanguage) {
        Language.JAVA -> "method"
        Language.KOTLIN -> "function"
    }
    is DProperty -> when (displayLanguage) {
        Language.JAVA -> "field"
        Language.KOTLIN -> "property"
    }
    is DObject -> "object"
    else -> error("Unsupported type: $this")
}

/* Returns if a class is an Exception or not
   isException, the built in method in Dokka, only considers its supertype so we also look for
   functions that are Throwable
   https://github.com/Kotlin/dokka/issues/1557
 */
val DClass.isExceptionClass: Boolean
    get() = isException || functions.any { function -> function.dri.classNames == "Throwable" }

// TODO(b/173138586) replace with something else when implementing JvmName
val DClasslike.isSynthetic: Boolean
    get() = name().endsWith("Kt")

/**
 * Converts a top level function to its representation under a Java synthetic class
 * and with JvmName
 * Replaces the dri to point to the synthetic class and applies the static modifier
 */
fun DFunction.withJavaSynthetic(syntheticClassName: String): DFunction {
    val jvmName = jvmName() ?: name
    return copy(
        name = jvmName,
        // this needs to be the dri IN the synthetic class
        dri = dri.copy(
            classNames = syntheticClassName,
            callable = dri.callable?.copy(name = jvmName)
        ),
        // put the static modifier on functions in the synthetic class
        extra = extra.addAll(sourceSets.map {
            mapOf(it to setOf(ExtraModifiers.JavaOnlyModifiers.Static)).toAdditionalModifiers()
        })
    )
}
/**
 * Converts a level function to its presentation with JvmName
 */
fun DFunction.withJvmName(): DFunction {
val jvmName = jvmName() ?: return this
    return copy(
        name = jvmName,
        dri = dri.copy(callable = dri.callable?.copy(name = jvmName))
    )
}
/**
 * Returns the value of the @JvmName for this function if one exists or null
 */
fun WithExtraProperties<*>.jvmName(): String? {
    val jvmNameAnnotation = annotations().filter { it.dri.classNames.equals("JvmName") }
    return if (jvmNameAnnotation.isEmpty()) {
        null
    } else {
        jvmNameAnnotation.first().params.getValue("name").toComponent().replace("\"", "")
    }
}

/**
 * Filters out elements that are annotated with @JvmSynthetic
 */
fun <T> List<T>.filterOutJvmSynthetic(): List<T>
    where T : WithExtraProperties<*> = this.filterNot {
        it.annotations().any { it.dri.classNames.equals("JvmSynthetic") }
    }
