/*
 * 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 com.android.build.shrinker.obfuscation

import com.android.build.shrinker.ResourceShrinkerModel
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path

/**
 * Records obfuscation mappings from single file in proguard format.
 *
 * @param mapping file lines or the mapping file path.
 */
class ProguardMappingsRecorder(private val mappingLines: List<String>) : ObfuscationMappingsRecorder {

    constructor(mappingsFile: Path)
      : this(Files.readAllLines(mappingsFile, StandardCharsets.UTF_8));

    override fun recordObfuscationMappings(model: ResourceShrinkerModel) {
        model.obfuscatedClasses = extractObfuscatedResourceClasses()
    }

    internal fun extractObfuscatedResourceClasses(): ObfuscatedClasses {
        // Proguard obfuscation mappings file has the following structure:
        // # comment1
        // com.package.MainClass -> a.a:
        //     int field -> a
        //     boolean getFlag() -> b
        // com.package.R -> a.b:
        // com.package.R$style -> a.b.a:
        //     int Toolbar_android_gravity -> i1
        val builder = ObfuscatedClasses.Builder()
        mappingLines.forEach { line ->
            when {
                isMethodMapping(line) -> builder.addMethodMapping(extractMethodMapping(line))
                isClassMapping(line) -> builder.addClassMapping(extractClassMapping(line))
            }
        }
        return builder.build()
    }

    private fun isClassMapping(line: String): Boolean = line.contains("->")

    private fun isMethodMapping(line: String): Boolean =
        (line.startsWith(" ") || line.startsWith("\t")) && line.contains("->")

    private fun extractClassMapping(line: String): Pair<String, String> {
        val mapping = line.split("->", limit = 2)
        return Pair(mapping[0].trim(), mapping[1].trim(' ', '\t', ':'))
    }

    private fun extractMethodMapping(line: String): Pair<String, String> {
        val mapping = line.split("->", limit = 2)
        val originalMethod = mapping[0].trim()
            .substringBeforeLast('(')
            .substringAfter(' ')
        val obfuscatedMethod = mapping[1].trim()
        return Pair(originalMethod, obfuscatedMethod)
    }
}
