package kotlinx.coroutines.experimental.tools

import org.objectweb.asm.*
import org.objectweb.asm.tree.*
import java.io.*
import java.util.jar.*

fun JarFile.classEntries() = entries().asSequence().filter {
    !it.isDirectory && it.name.endsWith(".class") && !it.name.startsWith("META-INF/")
}

fun getBinaryAPI(jar: JarFile, visibilityMap: Map<String, ClassVisibility>): List<ClassBinarySignature> =
    getBinaryAPI(jar.classEntries().map { entry -> jar.getInputStream(entry) }, visibilityMap)

fun getBinaryAPI(
    classStreams: Sequence<InputStream>,
    visibilityMap: Map<String, ClassVisibility>
): List<ClassBinarySignature> =
    classStreams.map {
        it.use { stream ->
            val classNode = ClassNode()
            ClassReader(stream).accept(classNode, ClassReader.SKIP_CODE)
            classNode
        }
    }.map {
        with(it) {
            val classVisibility = visibilityMap[name]
            val classAccess = AccessFlags(effectiveAccess and Opcodes.ACC_STATIC.inv())
            val supertypes = listOf(superName) - "java/lang/Object" + interfaces.sorted()

            val memberSignatures = (
                    fields.map {
                        with(it) {
                            FieldBinarySignature(
                                name,
                                desc,
                                isPublishedApi(),
                                AccessFlags(access)
                            )
                        }
                    } +
                            methods.map {
                                with(it) {
                                    MethodBinarySignature(
                                        name,
                                        desc,
                                        isPublishedApi(),
                                        AccessFlags(access)
                                    )
                                }
                            }
                    ).filter {
                it.isEffectivelyPublic(classAccess, classVisibility)
            }

            ClassBinarySignature(
                name,
                superName,
                outerClassName,
                supertypes,
                memberSignatures,
                classAccess,
                isEffectivelyPublic(classVisibility),
                isFileOrMultipartFacade() || isDefaultImpls()
            )
        }
    }.asIterable().sortedBy { it.name }


fun List<ClassBinarySignature>.filterOutNonPublic(nonPublicPackages: List<String> = emptyList()): List<ClassBinarySignature> {
    val nonPublicPaths = nonPublicPackages.map { it.replace('.', '/') + '/' }
    val classByName = associateBy { it.name }

    fun ClassBinarySignature.isInNonPublicPackage() =
        nonPublicPaths.any { name.startsWith(it) }

    fun ClassBinarySignature.isPublicAndAccessible(): Boolean =
        isEffectivelyPublic &&
                (outerName == null || classByName[outerName]?.let { outerClass ->
                    !(this.access.isProtected && outerClass.access.isFinal)
                            && outerClass.isPublicAndAccessible()
                } ?: true)

    fun supertypes(superName: String) = generateSequence({ classByName[superName] }, { classByName[it.superName] })

    fun ClassBinarySignature.flattenNonPublicBases(): ClassBinarySignature {

        val nonPublicSupertypes = supertypes(superName).takeWhile { !it.isPublicAndAccessible() }.toList()
        if (nonPublicSupertypes.isEmpty())
            return this

        val inheritedStaticSignatures =
            nonPublicSupertypes.flatMap { it.memberSignatures.filter { it.access.isStatic } }

        // not covered the case when there is public superclass after chain of private superclasses
        return this.copy(
            memberSignatures = memberSignatures + inheritedStaticSignatures,
            supertypes = supertypes - superName
        )
    }

    return filter { !it.isInNonPublicPackage() && it.isPublicAndAccessible() }
        .map { it.flattenNonPublicBases() }
        .filterNot { it.isNotUsedWhenEmpty && it.memberSignatures.isEmpty() }
}

fun List<ClassBinarySignature>.dump() = dump(to = System.out)

fun <T : Appendable> List<ClassBinarySignature>.dump(to: T): T = to.apply {
    this@dump.forEach {
        append(it.signature).appendln(" {")
        it.memberSignatures.sortedWith(MEMBER_SORT_ORDER).forEach { append("\t").appendln(it.signature) }
        appendln("}\n")
    }
}

