/*
 * 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.common.truth.Truth.assertThat
import com.google.devsite.capitalize
import com.google.devsite.components.DescriptionComponent
import com.google.devsite.components.Raw
import com.google.devsite.components.pages.Classlike
import com.google.devsite.components.pages.DevsitePage
import com.google.devsite.components.symbols.FunctionSignature
import com.google.devsite.components.symbols.SymbolDetail
import com.google.devsite.components.symbols.SymbolSummary
import com.google.devsite.components.table.SingleColumnSummaryItem
import com.google.devsite.components.table.SummaryList
import com.google.devsite.components.table.TableTitle
import com.google.devsite.renderer.Language
import com.google.devsite.renderer.converters.testing.content
import com.google.devsite.renderer.converters.testing.description
import com.google.devsite.renderer.converters.testing.item
import com.google.devsite.renderer.converters.testing.items
import com.google.devsite.renderer.converters.testing.link
import com.google.devsite.renderer.converters.testing.name
import com.google.devsite.renderer.converters.testing.projectionName
import com.google.devsite.renderer.converters.testing.size
import com.google.devsite.renderer.converters.testing.summary
import com.google.devsite.renderer.converters.testing.summaryItemsFor
import com.google.devsite.renderer.converters.testing.symbolsFor
import com.google.devsite.renderer.converters.testing.text
import com.google.devsite.renderer.converters.testing.title
import com.google.devsite.testing.ConverterTestBase
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.model.DModule
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import kotlin.test.assertFails

@RunWith(Parameterized::class)
internal class ClasslikeDocumentableConverterTest(
    private val displayLanguage: Language
) : ConverterTestBase(displayLanguage) {
    @Test
    fun `Classlike creates components with correct title`() {
        val page = """
            |class Foo
        """.render().page()

        assertThat(page.data.title).isEqualTo("Foo")
    }

    @Test
    fun `Classlike creates components with correct path`() {
        val page = """
            |class Foo
        """.render().page()

        assertThat(page.data.path).isEqualTo("androidx/example/Foo.html")
    }

    @Test
    fun `Classlike creates components with correct book path`() {
        val page = """
            |class Foo
        """.render().page()

        assertPath(page.data.bookPath, "androidx/_book.yaml")
    }

    @Test
    fun `Empty classlike has no symbols`() {
        val page = """
            |interface Foo
        """.render().page()

        val classlike = page.content<Classlike>()

        for ((summary, symbol) in classlike.data.symbolTypes) {
            assertThat(summary.hasContent()).isFalse()
            assertThat(symbol.symbols).isEmpty()
        }
    }

    @Test
    fun `Public function gets documented`() {
        val page = """
            |class Foo {
            |    fun foo() = Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val summary = classlike.methodSummaryItems()

        assertThat(summary.single().name()).isEqualTo("foo")
    }

    @Test
    fun `@jvmName functions get documented and sorted by correct name`() {
        val page = """
            |class Foo {
            |    @JvmName("bar")
            |    fun foo() = Unit
            |
            |    @JvmName("aar")
            |    fun zoo() = Unit
            |}
        """.render().page()

        javaOnly {
            val classlike = page.content<Classlike>()
            val (summary) = classlike.symbolsFor("Public methods")
            assertThat(summary.items().first().summary().name()).isEqualTo("aar")
            assertThat(summary.items().last().summary().name()).isEqualTo("bar")
        }
        kotlinOnly {
            val classlike = page.content<Classlike>()
            val (summary) = classlike.symbolsFor("Public functions")
            assertThat(summary.items().first().summary().name()).isEqualTo("foo")
            assertThat(summary.items().last().summary().name()).isEqualTo("zoo")
        }
    }

    @Test
    fun `Properties are documented in sorted order`() {
        val expected = listOf("a", "b", "c")
        val documentation = """
            |class Foo {
            |   /** @property b b_doc */
            |   public val b: String
            |   /** @property c c_doc */
            |   public val c: String
            |   /** @property a a_doc */
            |   public val a: String
            |}
        """.render().page()

        val propertiesSummary = documentation.content<Classlike>().propertySummaryItems()
        val props = propertiesSummary.items(3)

        for ((i, prop) in props.withIndex()) {
            assertThat((prop.data.description as SymbolSummary).name()).isEqualTo(expected[i])
        }
    }

    @Test
    fun `@JvmSynthetic methods are not documented in java`() {
        val page = """
            |class Foo {
            |    fun foo() = Unit
            |
            |    @JvmSynthetic
            |    fun zoo() = Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val summary = classlike.methodSummaryItems()

        javaOnly {
            assertThat(summary.size).isEqualTo(1)
        }
        kotlinOnly {
            assertThat(summary.size).isEqualTo(2)
        }
    }

    @Test
    fun `Protected function gets documented`() {
        val page = """
            |abstract class Foo {
            |    protected open fun foo() = Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor(protectedMethodsTitle(displayLanguage))

        assertThat(summary.item().summary().name()).isEqualTo("foo")
    }

    @Test
    fun `Public property gets documented`() {
        val page = """
            |class Foo {
            |    val foo = Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val summary = classlike.propertySummaryItems()

        assertThat(summary.single().summary().name()).isEqualTo("foo")
    }

    @Test
    fun `Protected property gets documented`() {
        val page = """
            |abstract class Foo {
            |    protected open val foo = Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor(protectedPropertiesTitle(displayLanguage))

        assertThat(summary.item().summary().name()).isEqualTo("foo")
    }

    @Test
    fun `Public constructor gets documented`() {
        val page = """
            |class Foo
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor("Public constructors")

        assertThat(summary.constructor().name()).isEqualTo("Foo")
    }

    @Test
    fun `Function summary component hides DeprecationLevel HIDDEN`() {
        val module = """
            |import kotlin.DeprecationLevel.HIDDEN
            |
            |class Visible {
            |   public val visible = "v"
            |   @Deprecated("No show!", level = HIDDEN)
            |   public val invisible = "i"
            |
            |   public fun show() = 7
            |   @Deprecated("No show!", level = HIDDEN)
            |   public fun noShow() = 5
            |}
            |
            |@Deprecated("No show!", level = HIDDEN)
            |class Nope
        """.render()

        assertThat(module.packages.single().classlikes.map { it.name }).containsExactly("Visible")
        val visible = module.page("Visible").content<Classlike>()

        assertThat(visible.methodSummaryItems().map { it.name() }).containsExactly("show")
        assertThat(visible.propertySummaryItems().map { it.name() }).containsExactly("visible")
    }

    @Test
    fun `Public constructor does not have @NonNull in 4x Kotlin and Java`() {
        val constructorsK = """
        |class Foo {
        |   constructor() {}
        |}
        """.render().page().content<Classlike>().symbolsFor("Public constructors")
        val constructorsJ = """
        |public class Foo {
        |   public Foo() {}
        |}
        """.render(java = true).page().content<Classlike>().symbolsFor("Public constructors")

        for (constructor in listOf(constructorsJ, constructorsK)) {
            // Constructor summaries are SingleColumnSummaryItems containing SymbolSummaries
            // They cannot have annotations, enforced by design.

            val detail = constructor.second.symbols.single() as SymbolDetail
            val returnAnnotations = detail.data.returnType.data.annotationComponents
            val annotations = detail.data.annotationComponents
            val signature = detail.data.signature as FunctionSignature
            assertThat(returnAnnotations.isEmpty())
            assertThat(annotations).isEmpty()
            assertThat(signature.data.receiver).isNull()
        }
    }

    @Test
    fun `Protected constructor gets documented`() {
        val page = """
            |open class Foo protected constructor()
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor("Protected constructors")

        assertThat(summary.constructor().name()).isEqualTo("Foo")
    }

    @Test
    fun `Nested type gets documented`() {
        val page = """
            |class Foo {
            |    class Bar
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor("Nested types")
        assertThat(summary.item().link().name).isEqualTo("Foo.Bar")
    }

    @Test
    fun `Companion objects are documented in Java but not Kotlin because they're inlined`() {
        val page = """
            |class Foo {
            |    companion object Bar
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val (summary) = classlike.symbolsFor("Nested types")
        kotlinOnly {
            assertThat(summary.items()).hasSize(0)
        }
        javaOnly {
            assertThat(summary.item().link().name).isEqualTo("Foo.Bar")
        }
    }

    @Test
    fun `Direct subclasses are found`() {
        val page = """
            |abstract class Foo
            |open class C : B
            |open class B : Foo
            |open class A : Foo
        """.render().page()

        val classlike = page.content<Classlike>()
        val subclasses = classlike.data.relatedSymbols.data.directSubclasses.items(2)

        assertThat(subclasses.first().data.name).isEqualTo("A")
        assertThat(subclasses.last().data.name).isEqualTo("B")
    }

    @Test
    fun `Indirect subclasses are found`() {
        val page = """
            |abstract class Foo
            |open class C : Foo
            |open class B : C
            |open class A : B
        """.render().page()

        val classlike = page.content<Classlike>()
        val subclasses = classlike.data.relatedSymbols.data.indirectSubclasses.items(2)

        assertThat(subclasses.first().data.name).isEqualTo("A")
        assertThat(subclasses.last().data.name).isEqualTo("B")
    }

    @Test
    fun `Class with root object as parent does not have hierarchy`() {
        val page = """
            |class Foo
        """.render().page()

        val classlike = page.content<Classlike>()
        val parents = classlike.data.hierarchy.data.parents

        assertThat(parents).isEmpty()
    }

    @Test
    fun `Class with single parent has hierarchy with root object, parent, and itself`() {
        val page = """
            |abstract class Parent
            |class Foo : Parent
        """.render().page()

        val classlike = page.content<Classlike>()
        val parents = classlike.data.hierarchy.data.parents.items(3).toList()

        javaOnly { assertThat(parents[0].data.name).isEqualTo("Object") }
        kotlinOnly { assertThat(parents[0].data.name).isEqualTo("Any") }
        assertThat(parents[1].data.name).isEqualTo("Parent")
        assertThat(parents[2].data.name).isEqualTo("Foo")
    }

    @Test
    fun `Class with multiple parents has hierarchy with root object and parents`() {
        val page = """
            |abstract class A
            |abstract class B : A
            |abstract class C : B
            |class Foo : C
        """.render().page()

        val classlike = page.content<Classlike>()
        val parents = classlike.data.hierarchy.data.parents.items(5).toList()

        javaOnly { assertThat(parents[0].data.name).isEqualTo("Object") }
        kotlinOnly { assertThat(parents[0].data.name).isEqualTo("Any") }
        assertThat(parents[1].data.name).isEqualTo("A")
        assertThat(parents[2].data.name).isEqualTo("B")
        assertThat(parents[3].data.name).isEqualTo("C")
        assertThat(parents[4].data.name).isEqualTo("Foo")
    }

    @Test
    fun `Class signature appears with extends and implements for internal types in 4x`() {
        val pageK = """
            |interface A
            |abstract class B
            |class Foo : A, B
        """.render().page("Foo")
        val pageJ = """
            |public interface A {}
            |public abstract class B {}
            |public class Foo extends Test.B implements Test.A {}
        """.render(java = true).page("Foo")

        for (page in listOf(pageJ, pageK)) {
            val prefix = if (page == pageK) "" else "Test."
            val classSignature = page.content<Classlike>().data.signature.data
            assertThat(classSignature.type).isEqualTo("class")
            assertThat(classSignature.extends.single().data.name).isEqualTo("${prefix}B")
            assertThat(classSignature.implements.single().data.name).isEqualTo("${prefix}A")
        }
    }

    @Ignore // b/170124934
    @Test
    fun `Class signature appears with extends or implements for external types in 4x`() {
        val pageExternalK = """
            |/**
            | * An implementation of [Lazy] used by [android.app.Activity.navArgs] and
            | * [androidx.fragment.app.Fragment.navArgs].
            | *
            | * [argumentProducer] is a lambda that will be called during initialization to provide
            | * arguments to construct an [Args] instance via reflection.
            | */
            |public class NavArgsLazy<Args : String>(
            |    private val navArgsClass: KClass<Args>,
            |    private val argumentProducer: () -> Bundle
            |) : Lazy<Args> {
        """.render().page(name = "NavArgsLazy")
        val pageExternalJ = """
            |public class JavaArgsLazy<Args extends String>() implements Lazy<Args> {}
        """.render(java = true).page(name = "NavArgsLazy")
    }

    @Test
    fun `Primary constructor can be @suppress-ed without hiding the class itself`() {
        // Primary constructor suppression is broken upstream
        // https://github.com/Kotlin/dokka/issues/1953
        val modulePrimary = """
            |public class BenchmarkState
            |    /** @suppress */
            |    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
            |    constructor(val foo: String) {
            |}
        """.render()
        assertFails {
            val page = modulePrimary.page("BenchmarkState")
        }
        // We can convert to equivalent secondary constructor and it works
        val moduleSecondary = """
            |public class BenchmarkState {
            |    val foo: String
            |    /** @suppress */
            |    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
            |    constructor(foo: String) { this.foo = foo }
            |}
        """.render()
        val page = moduleSecondary.page("BenchmarkState").content<Classlike>()
        assertThat(page.symbolsFor("Public constructors").first.size()).isEqualTo(0)
    }

    @Test
    fun `Enum class is rendered and has enum values with types in 4x Kotlin and Java`() {
        val pageK = """
            |/**
            | * class level docs
            | */
            |enum class AnEnumType {
            |    /**
            |     * content being refreshed, which can be a result of
            |     * invalidation, refresh that may contain content updates, or the initial load.
            |     */
            |    REFRESH,
            |    /**
            |     * Load at the start
            |     */
            |    PREPEND,
            |    /**
            |     * Load at the end.
            |     */
            |    APPEND
            |
            |    fun foo()
            |}
        """.render().page(name = "AnEnumType")
        val pageJ = """
            |/**
            | * class level docs
            | */
            |public enum AnEnumType {
            |    /**
            |     * content being refreshed, which can be a result of
            |     * invalidation, refresh that may contain content updates, or the initial load.
            |     */
            |    REFRESH,
            |    /**
            |     * Load at the start
            |     */
            |    PREPEND,
            |    /**
            |     * Load at the end.
            |     */
            |    APPEND
            |
            |    fun foo()
            |}
        """.render(java = true).page(name = "AnEnumType")

        for (page in listOf(pageK, pageJ)) {
            val classlike = page.content<Classlike>()
            val signature = classlike.data.signature.data
            val description = (classlike.data.description.first() as DescriptionComponent)

            val (enumSummary, enumDetails) = classlike.data.symbolTypes.first {
                (it.first as? SummaryList)?.title() == "Enum Values"
            }
            val enumTable = enumSummary.items(3) as List
            val enumOne = enumTable[0].data
            val enumTwo = enumTable[1].data
            val enumThree = enumTable[2].data

            assertThat(signature.type).isEqualTo("enum")
            assertThat(description.text()).isEqualTo("class level docs")

            assertThat((enumOne.title as Raw).data.text).contains("APPEND")
            assertThat((enumOne.description as DescriptionComponent).text())
                .contains("Load at the end.")
            assertThat((enumTwo.title as Raw).data.text).contains("PREPEND")
            assertThat((enumTwo.description as DescriptionComponent).text())
                .contains("Load at the start")
            assertThat((enumThree.title as Raw).data.text).contains("REFRESH")
            assertThat((enumThree.description as DescriptionComponent).text())
                .contains("result of invalidation")

            val enumName = enumDetails.symbols[0] as SymbolDetail
            val returnType = enumName.data.returnType.link()
            assertThat(returnType.name).endsWith("AnEnumType")
        }
    }

    @Test
    fun `Class component inherits docs from same language in 4x Kotlin and Java`() {
        val pagesK = """
            | /** docs for foo */
            |class foo() {
            |    /** dew it */
            |    fun doit() {}
            |    /** thunderous applause */
            |    open val democracy = false
            |}
            |class bar() : foo {
            |    override fun doit() {}
            |    override val democracy = true
            |}
            | /** overriding docs for baz */
            |class baz() : foo {
            |    /** overriding function docs */
            |    override fun doit() {}
            |    /** KotOR */
            |    override val democracy = true
            |}
            |class maz() : foo {
            |   /** {@inheritDoc} */
            |   override fun doit() {}
            |}        """.render()
        val pagesJ = """
            |public class foo {
            |    /** dew it */
            |    public void doit() {}
            |}
            |public class bar extends foo {
            |    /** {@inheritDoc} */
            |    @Override
            |    public void doit() {}
            |}
            |public class baz extends foo {
            |    /** overriding function docs */
            |    @Override
            |    public void doit() {}
            |}
        """.render(java = true) // Java {@inheritdoc} does not support classes & properties
        for (pages in listOf(pagesK, pagesJ)) {
            val fooClass = pages.page("foo").content<Classlike>()
            val barClass = pages.page("bar").content<Classlike>()
            val bazClass = pages.page("baz").content<Classlike>()

            // Function description inheritance does not work properly
            val fooDoit = fooClass.methodSummaryItems().single()
            val fooDoitDocs = fooDoit.summary().data.description.text()
            val barDoit = barClass.methodSummaryItems().single()
            val barDoitDocs = barDoit.summary().data.description.text()
            val bazDoit = bazClass.methodSummaryItems().single()
            val bazDoitDocs = bazDoit.summary().data.description.text()

            assertThat(fooDoitDocs).isEqualTo("dew it")
            assertThat(barDoitDocs).isEqualTo("dew it")
            assertThat(bazDoitDocs).isEqualTo("overriding function docs")

            if (pages == pagesK) {
                // overriding class docs is maybe something we want in kotlin, but is not jdoc spec
                val fooDescription = (fooClass.data.description.first() as DescriptionComponent)
                val barDescription = (barClass.data.description.first() as DescriptionComponent)
                val bazDescription = (bazClass.data.description.first() as DescriptionComponent)
                assertThat(fooDescription.text()).isEqualTo("docs for foo")
                // assertThat(barDescription.text()).isEqualTo("docs for foo")
                assertThat(bazDescription.text()).isEqualTo("overriding docs for baz")

                // overriding properties is kotlin-only, and working
                val fooDemocracy = fooClass.propertySummaryItems().single().summary()
                assertThat(fooDemocracy.data.description.text()).isEqualTo("thunderous applause")
                val barDemocracy = barClass.propertySummaryItems().single().summary()
                assertThat(barDemocracy.data.description.text()).isEqualTo("thunderous applause")
                val bazDemocracy = bazClass.propertySummaryItems().single().summary()
                assertThat(bazDemocracy.data.description.text()).isEqualTo("KotOR")

                // Using {@inheritDoc} in kotlin is wrong
                val mazClass = pages.page("maz").content<Classlike>()
                val mazDoit = mazClass.methodSummaryItems().single()
                val mazDoitDocs = mazDoit.summary().data.description.text()
                assertThat(mazDoitDocs).isNotEqualTo("dew it")
            }
        }
    }

    @Ignore // TODO: patch upstream dokka to implement kotlin documentation inheritance b/184361891
    @Test // TODO: add @constructor doc inheritance tests once that is implemented
    fun `Property parameter documentation inherits properly`() {
        val pages = """
            |/**
            | * @param param1 param1_docs
            | * @property property1 property1_docs
            | */
            |class supclaz(val param1: String, val property1: Int) {}
            |/**
            | * @param param2 param2_docs
            | * @property property2 property2_docs
            | */
            |interface interfaz(val param2: String, val property2: Int) {}
            |/**
            | * @param param3 param3_docs
            | * @property property3 property3_docs
            | */
            |sealed class sealclaz(internal val param3: String, protected val property3: Int) {}
            |class foo(param1: String, property1: Int, param2: String, property2: Int): supclaz(param1, property1), interfaz(param2, property2)
            |/**
            | * @param param1 override_param1_docs
            | * @param param2 override_param2_docs
            | * @property property1 override_property1_docs
            | * @property property2 override_property2_docs
            | */
            |class baz(param1: String, property1: Int, param2: String, property2: Int): supclaz(param1, property1), interfaz(param2, property2)
            |class bar(param3: String, property3: Int): sealclaz(param3, property3)
        """.render()
        val fooClass = pages.page("foo").content<Classlike>()
        val pparam1docs = fooClass.propertySymbol("param1").description()
        val pparam2docs = fooClass.propertySymbol("param2").description()
        val prop1docs = fooClass.propertySymbol("property1").description()
        val prop2docs = fooClass.propertySymbol("property2").description()
        val param1docs = (
            (
                fooClass.symbolsFor("Public constructors").second
                    .symbols.single() as SymbolDetail
                ).data.metadata[1] as SummaryList
            )
            .items().single { it.name() == "param1" }.description()
        val param2docs = (
            (
                fooClass.symbolsFor("Public constructors").second
                    .symbols.single() as SymbolDetail
                ).data.metadata[1] as SummaryList
            )
            .items().single { it.name() == "param2" }.description()
        assertThat(pparam1docs.text()).isEqualTo("param1_docs")
        assertThat(prop1docs.text()).isEqualTo("property1_docs")
        assertThat(pparam2docs.text()).isEqualTo("param2_docs")
        assertThat(prop2docs.text()).isEqualTo("property2_docs")
        assertThat(param1docs.text()).isEqualTo("param1_docs")
        assertThat(param2docs.text()).isEqualTo("param2_docs")
        val bazClass = pages.page("baz").content<Classlike>()
        val zpparam1docs = bazClass.propertySymbol("param1").description()
        val zpparam2docs = bazClass.propertySymbol("param2").description()
        val zprop1docs = bazClass.propertySymbol("property1").description()
        val zprop2docs = bazClass.propertySymbol("property2").description()
        val zparam1docs = (
            (
                bazClass.symbolsFor("Public constructors").second
                    .symbols.single() as SymbolDetail
                ).data.metadata[1] as SummaryList
            )
            .items().single { it.name() == "param1" }.description()
        val zparam2docs = (
            (
                bazClass.symbolsFor("Public constructors").second
                    .symbols.single() as SymbolDetail
                ).data.metadata[1] as SummaryList
            )
            .items().single { it.name() == "param2" }.description()
        assertThat(zpparam1docs.text()).isEqualTo("override_param1_docs")
        assertThat(zprop1docs.text()).isEqualTo("override_property1_docs")
        assertThat(zpparam2docs.text()).isEqualTo("override_param2_docs")
        assertThat(zprop2docs.text()).isEqualTo("override_property2_docs")
        assertThat(zparam1docs.text()).isEqualTo("override_param1_docs")
        assertThat(zparam2docs.text()).isEqualTo("override_param2_docs")
        val barClass = pages.page("bar").content<Classlike>()
        // TODO: patch upstream? dokka to support inheriting documentation on hidden components
        val pparam3docs = barClass.propertySymbol("param3").description()
        val prop3docs = barClass.propertySymbol("property3").description()
        val param3docs = (
            (
                barClass.symbolsFor("Public constructors").second
                    .symbols.single() as SymbolDetail
                ).data.metadata[1] as SummaryList
            )
            .items().single { it.name() == "param3" }.description()
        assertThat(pparam3docs.text()).isEqualTo("param3_docs")
        assertThat(prop3docs.text()).isEqualTo("property3_docs")
        assertThat(param3docs.text()).isEqualTo("param3_docs")
    }

    @Test
    fun `Level-jumping doc inheritance works in 4x Kotlin and Java`() {
        val pageK = """
            | /** docs for foo */
            |class foo() {
            |    /** dew it */
            |    fun doit() {}
            |}
            |class bar() : foo {}
            | /** overriding docs for baz */
            |class baz() : bar {
            |    override fun doit() {}
            |}
        """.render().page("baz")
        val pageJ = """
            | /** docs for foo */
            |public class foo() {
            |    /** dew it */
            |    public void doit() {}
            |}
            |public class bar() extends foo {}
            | /** overriding docs for baz */
            |public class baz() extends bar {
            |    /** {@inheritdoc} */
            |    override public void doit() {}
            |}
        """.render(java = true).page("baz")
        for (page in listOf(pageJ, pageK)) {
            val doit = page.content<Classlike>().methodSummaryItems().single()
            assertThat(doit.summary().data.description.text()).isEqualTo("dew it")
        }
    }

    @Test
    fun `Inherited methods are sorted by name and arity`() {
        val childClass = """
            |class Parent() {
            |    fun b(input: Int, zinput2: Int) {}
            |    fun c() {}
            |    fun a() {}
            |    fun b(input: Int, input2: Int) {}
            |    fun b() {}
            |    fun b(input: Int) {}
            |}
            |class Child() : Parent {}
        """.render().page("Child").content<Classlike>()
        val inheritedSummary = childClass.data.inheritedTypes.single().data.inheritedSymbolSummaries
        val inheritedMethods = inheritedSummary.entries.single().value.data.items
        val inheritedMethodSignatures = inheritedMethods.map {
            (it.data.description as SymbolSummary).data.signature as FunctionSignature
        }
        assertThat(inheritedMethodSignatures.map { it.data.name.data.name }).isEqualTo(
            listOf("a", "b", "b", "b", "b", "c")
        )
        assertThat(inheritedMethodSignatures.map { it.data.parameters.size }).isEqualTo(
            listOf(0, 0, 1, 2, 2, 0)
        )
        val paramNames = inheritedMethodSignatures.map {
            it.data.parameters.map { it.data.name }
        }
        assertThat(paramNames).isEqualTo(
            listOf(
                listOf(),
                listOf(),
                listOf("input"),
                listOf("input", "input2"),
                listOf("input", "zinput2"),
                listOf()
            )
        )
    }

    @Test
    fun `Inherited properties are not lost`() {
        val page = """
            |open class Parent {
            |    val b: Int = 8
            |    val a: String = "9"
            |}
            |class Child: Parent()
        """.render().page("Child").content<Classlike>()

        val category = page.data.inheritedTypes.single().data.inheritedSymbolSummaries
        val names = category.values.single().items().map { it.name() }

        assertThat(names).containsExactly("a", "b").inOrder()
    }

    @Test
    fun `Different categories of symbols inherited from different classes works`() {
        val page = """
            |open class GrandParent {
            |    val grandC: Int = 18
            |    fun grandA(): String = "9"
            |    fun grandB(): {}
            |}
            |open class Parent: GrandParent {
            |    val parentB: Int = 8
            |    val parentA: String = "9"
            |    fun parentC(): {}
            |}
            |class Child: Parent()
        """.render().page("Child").content<Classlike>()

        val categoriesNames = page.data.inheritedTypes.map {
            (it.data.header as TableTitle).data.title
        }
        kotlinOnly {
            assertThat(categoriesNames)
                .containsExactly("Inherited functions", "Inherited properties").inOrder()
        }
        javaOnly {
            assertThat(categoriesNames)
                .containsExactly("Inherited methods", "Inherited fields").inOrder()
        }

        val functions = page.data.inheritedTypes.first().data.inheritedSymbolSummaries
            .mapKeys { it.key.data.name }
            .mapValues { (_, list) -> list.items().map { it.name() } }
        assertThat(functions).containsExactly(
            "GrandParent", listOf("grandA", "grandB"),
            "Parent", listOf("parentC")
        )

        val properties = page.data.inheritedTypes.last().data.inheritedSymbolSummaries
            .mapKeys { it.key.data.name }
            .mapValues { (_, list) -> list.items().map { it.name() } }
        assertThat(properties).containsExactly(
            "GrandParent", listOf("grandC"),
            "Parent", listOf("parentA", "parentB")
        )
    }

    @Test
    fun `Class component creates inline generics`() {
        val page = """
            |class Foo<T: Number, U>() {}
        """.render().page()
        val typeParams = page.content<Classlike>().data.signature.data.typeParameters
        assertThat(typeParams.first().data.name).isEqualTo("T")
        assertThat(typeParams.first().projectionName()).isEqualTo("Number")
        assertThat(typeParams.last().data.name).isEqualTo("U")
        kotlinOnly { assertThat(typeParams.last().projectionName()).isEqualTo("Any") }
        javaOnly { assertThat(typeParams.last().projectionName()).isEqualTo("Object") }
    }

    @Test
    fun `Class component creates all symbols in the correct order`() {
        val page = "class Foo {}".render().page()
        val symbolTypes = page
            .content<Classlike>()
            .data
            .symbolTypes
            .map { it.second.title }

        javaOnly {
            assertThat(symbolTypes).isEqualTo(
                listOf(
                    "Nested types",
                    "Enum Values",
                    "Constants",
                    "Public fields",
                    "Protected fields",
                    "Public constructors",
                    "Protected constructors",
                    "Public methods",
                    "Protected methods"
                )
            )
        }

        kotlinOnly {
            assertThat(symbolTypes).isEqualTo(
                listOf(
                    "Nested types",
                    "Enum Values",
                    "Constants",
                    "Public companion functions",
                    "Protected companion functions",
                    "Public companion properties",
                    "Protected companion properties",
                    "Public constructors",
                    "Protected constructors",
                    "Public functions",
                    "Protected functions",
                    "Public properties",
                    "Protected properties"
                )
            )
        }
    }

    @Test
    fun `classlike companion functions are included in Kotlin and not Java`() {
        val page = """
            |class Foo {
            |  companion object {
            |    fun bar() = Unit
            |    fun baz() = Unit
            |  }
            |}
        """.render().page()

        val classlike = page.content<Classlike>()

        kotlinOnly {
            val companionFunctions = classlike.summaryItemsFor(publicCompanionFunctionsTitle())
            assertThat(companionFunctions).hasSize(2)
        }
        javaOnly {
            classlike.assertNoSymbolsFor(protectedCompanionFunctionsTitle())
        }
    }

    @Test
    fun `protected companion functions are included in Kotlin and not Java`() {
        val page = """
            |class Foo {
            |  companion object {
            |    protected fun bar() = Unit
            |  }
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        kotlinOnly {
            val companionFunctions = classlike.summaryItemsFor(protectedCompanionFunctionsTitle())
            assertThat(companionFunctions).hasSize(1)
        }
        javaOnly {
            classlike.assertNoSymbolsFor(protectedCompanionFunctionsTitle())
        }
    }

    @Test
    fun `classlike companion properties are included in Kotlin and not Java`() {
        val page = """
            |class Foo {
            |  companion object {
            |    val bar: List<String> = emptyList()
            |    protected val baz: Int = 1
            |  }
            |}
        """.render().page()

        val classlike = page.content<Classlike>()

        kotlinOnly {
            val publicCompanionProperties = classlike
                .summaryItemsFor(publicCompanionPropertiesTitle())
            val protectedCompanionProperties = classlike
                .summaryItemsFor(protectedCompanionPropertiesTitle())
            assertThat(publicCompanionProperties).hasSize(1)
            assertThat(protectedCompanionProperties).hasSize(1)
        }
        javaOnly {
            classlike.assertNoSymbolsFor(publicCompanionPropertiesTitle())
            classlike.assertNoSymbolsFor(protectedCompanionPropertiesTitle())
        }
    }

    @Test
    fun `Static and companion functions are treated correctly in both languages`() {
        val moduleK = """
            |class Foo {
            |  companion object {
            |    val baz: Int = 1
            |    fun bar() = Unit
            |  }
            |}
        """.render()
        val classlikeK = moduleK.page().content<Classlike>()

        val classlikeJ = """
            |public class Foo {
            |  public static void foo() {}
            |  public static String bar = "bar"
            |}
        """.render(java = true).page().content<Classlike>()

        val companionClassK = moduleK.page("Companion")

        val (kotlinNestedTypeSummary) = classlikeK.symbolsFor("Nested types")

        val staticJavaMethod = classlikeJ.methodDetailsItems().single().data
        val staticJavaField = classlikeJ.propertyDetailsItems().single().data

        // Companion class is included in both modules
        assertThat(companionClassK).isNotNull()

        // can see java static methods in both languages
        assertThat(staticJavaMethod.name).isEqualTo("foo")
        assertThat(staticJavaField.name).isEqualTo("bar")

        // can find kotlin companion method in both languages
        kotlinOnly {
            // nested companion object is not documented because it is inlined
            assertThat(kotlinNestedTypeSummary.items()).hasSize(0)
            val companionFunctions = classlikeK.summaryItemsFor(publicCompanionFunctionsTitle())
            val companionProperties = classlikeK.summaryItemsFor(publicCompanionPropertiesTitle())
            assertThat(companionFunctions).hasSize(1)
            assertThat(companionProperties).hasSize(1)
        }
        javaOnly {
            // nested companion object is documented but companion functions are not inlined
            assertThat(kotlinNestedTypeSummary.items()).hasSize(1)
            classlikeK.assertNoSymbolsFor(publicCompanionFunctionsTitle())
            classlikeK.assertNoSymbolsFor(publicCompanionPropertiesTitle())
            assertThat(staticJavaMethod.modifiers).contains("static")
            assertThat(staticJavaField.modifiers).contains("static")
        }
    }

    @Test
    fun `Extension functions are included on Java and Kotlin pages`() {
        val src = """
            |class Foo {
            |}
            |fun Foo.bar() = Unit
            |fun Foo.baz() = Unit
        """
        val classlike = src.render().page().content<Classlike>()
        val extFunctions = classlike.symbolsFor("Extension functions")
        assertThat(extFunctions.first.data.items).hasSize(2)
    }

    @Test
    fun `Extension functions are ordered by the package they come from`() {
        val src = listOf(
            """
                |/src/main/kotlin/androidx/example/Foo.kt
                |package foo
                |class Foo {
                |}
            """,
            """
                |/src/main/kotlin/androidx/example/Second.kt
                |package second
                |
                |import foo.Foo
                |
                |fun Foo.baz() = Unit
            """,
            """
                |/src/main/kotlin/androidx/example/First.kt
                |package first
                |
                |import foo.Foo
                |
                |fun Foo.zab() = Unit
            """
        )
        val classlike = src.render().page().content<Classlike>()
        val extFunctions = classlike.symbolsFor("Extension functions")
        val extFunctionClasses = extFunctions.second.symbols.map {
            (it as? SymbolDetail)?.data?.extFunctionClass
        }
        assertThat(extFunctionClasses).isEqualTo(listOf("FirstKt", "SecondKt"))
    }

    @Test
    fun `Extension functions respect @JvmName for packages`() {
        val src = listOf(
            """
                |/src/main/kotlin/androidx/example/Foo.kt
                |package foo
                |class Foo {
                |}
            """,
            """
                |/src/main/kotlin/androidx/example/Second.kt
                |
                |@file:JvmName("SecondJvm")
                |package second
                |
                |import foo.Foo
                |
                |fun Foo.baz() = Unit
            """,
            """
                |/src/main/kotlin/androidx/example/First.kt
                |
                |@file:JvmName("FirstJvm")
                |package first
                |
                |
                |import foo.Foo
                |
                |fun Foo.zab() = Unit
            """
        )
        val classlike = src.render().page().content<Classlike>()
        val extFunctions = classlike.symbolsFor("Extension functions")
        val extFunctionClasses = extFunctions.second.symbols.map {
            (it as? SymbolDetail)?.data?.extFunctionClass
        }
        assertThat(extFunctionClasses).isEqualTo(listOf("FirstJvm", "SecondJvm"))
    }

    @Ignore // TODO: b/195529157
    @Test
    fun `Annotation types with no parameters have no default constructors`() {
        // parameterless annotations are invoked as `@NonNull` not `@NonNull()`
        val documentationJ = """
        |public @interface Mega {
        |   /**
        |    * Reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code true}. One
        |    * of {@link #PLAYBACK_SUPPRESSION_REASON_NONE} or {@link
        |    * #PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS}.
        |    */
        |   @Documented
        |   @Retention(RetentionPolicy.SOURCE)
        |   @interface PlaybackSuppressionReason {}
        |}
        """.render(java = true).page("PlaybackSuppressionReason").content<Classlike>()
        val documentationK = """
        |public annotation class Mega {
        |   /**
        |    * Reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code true}. One
        |    * of {@link #PLAYBACK_SUPPRESSION_REASON_NONE} or {@link
        |    * #PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS}.
        |    */
        |   annotation class PlaybackSuppressionReason {}
        |}
        """.render().page("PlaybackSuppressionReason").content<Classlike>()

        for (documentation in listOf(documentationJ, documentationK)) {
            val constructors = documentation.symbolsFor("public constructors")
            assertThat(constructors.first.size()).isEqualTo(0)
        }
    }

    @Test
    fun `Java getters and setters are documented`() {
        val page = """
            |public final class Foo {
            |
            |  public int a;
            |  public int c; // intentional mismatch of field name / getter name
            |  private int d;
            |  protected int e;
            |
            |  public int getA() {
            |    return a;
            |  }
            |
            |  public void setA(int a) {
            |    this.a = a;
            |  }
            |
            |  public int getB() {
            |    return c;
            |  }
            |
            |  public void setB(int b) {
            |    c = b;
            |  }
            |
            |  private int getD() {
            |    return d;
            |  }
            |
            |  private void setD(int d) {
            |    this.d = d;
            |  }
            |
            |  protected int getE() {
            |    return e;
            |  }
            |
            |  protected void setE(int e) {
            |    this.e = e;
            |  }
            |}
        """.render(java = true).page()

        val classlike = page.content<Classlike>()
        val publicMethodSymbols = classlike.symbolsFor(publicMethodsTitle(displayLanguage))
        val protectedMethodSymbols = classlike.symbolsFor(protectedMethodsTitle(displayLanguage))
        val publicMethodNames = publicMethodSymbols.second.symbols.map {
            (it as SymbolDetail).data.name
        }
        val protectedMethodNames = protectedMethodSymbols.second.symbols.map {
            (it as SymbolDetail).data.name
        }

        kotlinOnly {
            // in Kotlin, we don't need to show getA / setA because property access is preferred.
            assertThat(publicMethodNames).isEqualTo(listOf("getB", "setB"))
            assertThat(protectedMethodNames).isEmpty()
        }
        javaOnly {
            assertThat(publicMethodNames).isEqualTo(listOf("getA", "getB", "setA", "setB"))
            // TODO(b/165112358): 'e' doesn't show up in the dokka model
            // assertThat(protectedMethodNames).isEqualTo(listOf("getE", "setE"))
        }
    }

    @Test
    fun `Java source with public getter and private setter is documented correctly`() {
        val page = """
            |public final class Foo {
            |
            |  public int a;
            |
            |  public int getA() {
            |    return a;
            |  }
            |
            |  private void setA(int a) {
            |    this.a = a;
            |  }
            |}
        """.render(java = true).page()

        val classlike = page.content<Classlike>()
        val publicMethodSymbols = classlike.methodDetailsItems()
        val publicMethodNames = publicMethodSymbols.map { it.data.name }

        kotlinOnly {
            assertThat(publicMethodNames).isEmpty()
        }
        javaOnly {
            assertThat(publicMethodNames).isEqualTo(listOf("getA"))
        }
    }

    @Test
    fun `Kotlin generated getters and setters are not documented`() {
        val page = """
            |data class Foo(val a: Int, var b: Int) {
            |    var c: Int
            |       get() = 0
            |       set(c: Int): Unit
            |}
        """.render().page()

        val classlike = page.content<Classlike>()
        val methodSymbols = classlike.methodDetailsItems()
        val methodNames = methodSymbols.map { it.data.name }

        assertThat(methodNames).isEmpty()
    }

    @Test
    fun `Default no-arg constructors are autogenerated`() {
        val emptyTestClass = """
            public class Foo {}
        """.trimIndent()

        for (isJava in listOf(true, false)) {
            val classlike = emptyTestClass.render(java = isJava).page("Foo").content<Classlike>()
            val constructorList = classlike.symbolsFor("Public constructors").second.symbols
            assertThat(constructorList.size).isEqualTo(1)
            assertThat((constructorList.single() as SymbolDetail).data.name).isEqualTo("Foo")
        }
    }

    @Test
    fun `Default no-arg constructors are not autogenerated for annotations`() {
        val classlikeJ = """
            public @interface Foo {}
        """.trimIndent().render(java = true).page("Foo").content<Classlike>()
        val classlikeK = """
            public annotation class Foo {}
        """.trimIndent().render(java = false).page("Foo").content<Classlike>()

        for (classlike in listOf(classlikeJ/*, classlikeK*/)) { // TODO: b/195529157
            val constructorList = classlike.symbolsFor("Public constructors").second.symbols
            assertThat(constructorList).isEmpty()
        }
    }

    @Test // Interfaces "extend" other interfaces, while classes "implement" interfaces
    fun `Interface extending another interface uses correct keyword`() {
        val signatureJ = """
            public interface Foo {}
            public interface Bar extends Foo {}
        """.trimIndent().render(java = true).page("Bar").content<Classlike>().data.signature
        val signatureK = """
            public interface Foo {}
            public interface Bar : Foo {}
        """.trimIndent().render(java = false).page("Bar").content<Classlike>().data.signature

        assertThat(signatureJ.data.extends).isEmpty()
        assertThat(signatureK.data.extends).isEmpty()
        assertThat(signatureJ.data.implements.single().data.name).isEqualTo("Test.Foo")
        assertThat(signatureK.data.implements.single().data.name).isEqualTo("Foo")
        // Now route to DefaultClassSignatureTest.`Interfaces extend other interfaces`()
    }

    private fun DModule.page(name: String = "Foo"): DevsitePage {
        val classlike = explicitClasslike(name)
        val (holder, pathProvider) = holderAndProvider(this)
        val extFunctionMap = runBlocking { holder.extensionFunctionMap() }
        val converter = ClasslikeDocumentableConverter(
            displayLanguage,
            classlike,
            pathProvider,
            holder,
            extFunctionMap.getOrDefault(name, emptyList())
        )
        return runBlocking { converter.classlike() }
    }

    private fun String.possiblyAsGetter() = if (displayLanguage == Language.KOTLIN) this
    else "get" + this.capitalize()

    private fun Classlike.methodDetailsItems() = (
        symbolsFor(publicMethodsTitle(displayLanguage)).second.symbols +
            symbolsFor(protectedMethodsTitle(displayLanguage)).second.symbols
        ).map { it as SymbolDetail }

    private fun Classlike.methodSummaryItems() =
        summaryItemsFor(publicMethodsTitle(displayLanguage)) +
            summaryItemsFor(protectedMethodsTitle(displayLanguage))

    private fun Classlike.methodSymbol(name: String = "foo") =
        methodSummaryItems().singleOrNull { it.name() == name }
            ?: methodSummaryItems().single()

    private fun Classlike.propertySummaryItems() =
        summaryItemsFor(publicPropertiesTitle(displayLanguage)) +
            summaryItemsFor(protectedPropertiesTitle(displayLanguage))

    private fun Classlike.propertyDetailsItems() = (
        symbolsFor(publicPropertiesTitle(displayLanguage)).second.symbols +
            symbolsFor(protectedPropertiesTitle(displayLanguage)).second.symbols
        ).map { it as SymbolDetail }

    private fun Classlike.propertySymbol(name: String = "foo") =
        propertySummaryItems().singleOrNull { it.name() == name }
            ?: propertySummaryItems().single()

    private fun SummaryList.constructor() =
        (data.items.item() as SingleColumnSummaryItem).data.description as SymbolSummary

    private fun Classlike.assertNoSymbolsFor(symbolsName: String) = assertThat(
        data.symbolTypes.none { it.first.title() == symbolsName }
    ).isTrue()

    companion object {
        @JvmStatic
        @Parameterized.Parameters(name = "{0}")
        fun data() = listOf(
            arrayOf(Language.JAVA),
            arrayOf(Language.KOTLIN)
        )
    }
}
