/*
 * Copyright 2018 The Bazel Authors. All rights reserved.
 *
 * 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 io.bazel.kotlin.builder.tasks.jvm

import com.google.devtools.build.lib.view.proto.Deps
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
import java.util.function.Predicate
import java.util.stream.Stream

class JdepsParser private constructor(private val filename: String, private val isImplicit: Predicate<String>) {
    private val packageSuffix: String = " ($filename)"

    private val depMap = HashMap<String, Deps.Dependency.Builder>()
    private val packages = HashSet<String>()

    private var mode = Mode.COLLECT_DEPS

    private fun consumeJarLine(classJarPath: String, kind: Deps.Dependency.Kind) {
        val path = Paths.get(classJarPath)

        // ignore absolute files, -- jdk jar paths etc.
        // only process jar files
        if (!(path.isAbsolute || !classJarPath.endsWith(".jar"))) {
            val entry = depMap.computeIfAbsent(classJarPath) {
                val depBuilder = Deps.Dependency.newBuilder()
                depBuilder.path = classJarPath
                depBuilder.kind = kind

                if (isImplicit.test(classJarPath)) {
                    depBuilder.kind = Deps.Dependency.Kind.IMPLICIT
                }
                depBuilder
            }

            // don't flip an implicit dep.
            if (entry.kind != Deps.Dependency.Kind.IMPLICIT) {
                entry.kind = kind
            }
        }
    }

    private enum class Mode {
        COLLECT_DEPS,
        DETERMINE_JDK,
        COLLECT_PACKAGES_JDK8,
        COLLECT_PACKAGES_JDK9
    }

    // maybe simplify this by tokenizing on whitespace and arrows.
    private fun processLine(line: String) {
        val trimmedLine = line.trim { it <= ' ' }
        when (mode) {
            Mode.COLLECT_DEPS -> if (!line.startsWith(" ")) {
                val parts = line.split(" -> ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                if (parts.size == 2) {
                    if (parts[0] != filename) {
                        throw RuntimeException("should only get dependencies for dep: $filename")
                    }
                    consumeJarLine(parts[1], Deps.Dependency.Kind.EXPLICIT)
                }
            } else {
                mode = Mode.DETERMINE_JDK
                processLine(line)
            }
            Mode.DETERMINE_JDK -> {
                mode = Mode.COLLECT_PACKAGES_JDK8
                if (!line.endsWith(packageSuffix)) {
                    mode = Mode.COLLECT_PACKAGES_JDK9
                }
                processLine(line)
            }
            Mode.COLLECT_PACKAGES_JDK8 -> when {
                trimmedLine.endsWith(packageSuffix) -> packages.add(trimmedLine.substring(0, trimmedLine.length - packageSuffix.length))
                trimmedLine.startsWith("-> ") -> {
                    // ignore package detail lines, in the jdk8 format these start with arrows.
                }
                else -> throw RuntimeException("unexpected line while collecting packages: $line")
            }
            Mode.COLLECT_PACKAGES_JDK9 -> {
                val pkg = trimmedLine.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                packages.add(pkg[0])
            }
        }
    }

    companion object {
        fun pathSuffixMatchingPredicate(directory: Path, vararg jars: String): Predicate<String> {
            val suffixes = jars.map { directory.resolve(it).toString() }
            return Predicate { jar ->
                for (implicitJarsEnding in suffixes) {
                    if (jar.endsWith(implicitJarsEnding)) {
                        return@Predicate true
                    }
                }
                false
            }
        }

        fun parse(
            label: String,
            classJar: String,
            classPath: String,
            jdepLines: List<String>,
            isImplicit: Predicate<String>
        ): Deps.Dependencies {
            val filename = Paths.get(classJar).fileName.toString()
            val jdepsParser = JdepsParser(filename, isImplicit)
            Stream.of(*classPath.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
                .forEach { x -> jdepsParser.consumeJarLine(x, Deps.Dependency.Kind.UNUSED) }
            jdepLines.forEach { jdepsParser.processLine(it) }

            val rootBuilder = Deps.Dependencies.newBuilder()
            rootBuilder.success = false
            rootBuilder.ruleLabel = label

            rootBuilder.addAllContainedPackage(jdepsParser.packages)
            jdepsParser.depMap.values.forEach { b -> rootBuilder.addDependency(b.build()) }

            rootBuilder.success = true
            return rootBuilder.build()
        }
    }
}