/*
 * Copyright (C) 2022 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;

import com.android.build.shrinker.gatherer.ProtoResourceTableGatherer;
import com.android.build.shrinker.gatherer.ResourcesGatherer;
import com.android.build.shrinker.graph.ProtoResourcesGraphBuilder;
import com.android.build.shrinker.usages.DexUsageRecorder;
import com.android.build.shrinker.usages.ProtoAndroidManifestUsageRecorder;
import com.android.build.shrinker.usages.ResourceUsageRecorder;
import com.android.build.shrinker.usages.ToolsAttributeUsageRecorder;
import com.android.utils.FileUtils;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;

public class ResourceShrinkerCli {

    private static final String INPUT_ARG = "--input";
    private static final String DEX_INPUT_ARG = "--dex_input";
    private static final String OUTPUT_ARG = "--output";
    private static final String RES_ARG = "--raw_resources";
    private static final String HELP_ARG = "--help";
    private static final String PRINT_USAGE_LOG = "--print_usage_log";

    private static final String ANDROID_MANIFEST_XML = "AndroidManifest.xml";
    private static final String RESOURCES_PB = "resources.pb";
    private static final String RES_FOLDER = "res";

    private static class Options {
        private String input;
        private final List<String> dex_inputs = new ArrayList<>();
        private String output;
        private String usageLog;
        private final List<String> rawResources = new ArrayList<>();
        private boolean help;

        private Options() {}

        public static Options parseOptions(String[] args) {
            Options options = new Options();
            for (int i = 0; i < args.length; i++) {
                String arg = args[i];
                if (arg.startsWith(INPUT_ARG)) {
                    i++;
                    if (i == args.length) {
                        throw new ResourceShrinkingFailedException("No argument given for input");
                    }
                    if (options.input != null) {
                        throw new ResourceShrinkingFailedException(
                                "More than one input not supported");
                    }
                    options.input = args[i];
                } else if (arg.startsWith(OUTPUT_ARG)) {
                    i++;
                    if (i == args.length) {
                        throw new ResourceShrinkingFailedException("No argument given for output");
                    }
                    if (options.output != null) {
                        throw new ResourceShrinkingFailedException(
                                "More than one output not supported");
                    }
                    options.output = args[i];
                } else if (arg.startsWith(DEX_INPUT_ARG)) {
                    i++;
                    if (i == args.length) {
                        throw new ResourceShrinkingFailedException(
                                "No argument given for dex_input");
                    }
                    options.dex_inputs.add(args[i]);
                } else if (arg.startsWith(PRINT_USAGE_LOG)) {
                    i++;
                    if (i == args.length) {
                        throw new ResourceShrinkingFailedException(
                                "No argument given for usage log");
                    }
                    if (options.usageLog != null) {
                        throw new ResourceShrinkingFailedException(
                                "More than usage log not supported");
                    }
                    options.usageLog = args[i];
                } else if (arg.startsWith(RES_ARG)) {
                    i++;
                    if (i == args.length) {
                        throw new ResourceShrinkingFailedException(
                                "No argument given for raw_resources");
                    }
                    options.rawResources.add(args[i]);
                } else if (arg.equals(HELP_ARG)) {
                    options.help = true;
                } else {
                    throw new ResourceShrinkingFailedException("Unknown argument " + arg);
                }
            }
            return options;
        }

        public String getInput() {
            return input;
        }

        public String getOutput() {
            return output;
        }

        public String getUsageLog() {
            return usageLog;
        }

        public List<String> getRawResources() {
            return rawResources;
        }

        public boolean isHelp() {
            return help;
        }
    }

    public static void main(String[] args) {
        run(args);
    }

    protected static ResourceShrinkerImpl run(String[] args) {
        try {
            Options options = Options.parseOptions(args);
            if (options.isHelp()) {
                printUsage();
                return null;
            }
            validateOptions(options);
            ResourceShrinkerImpl resourceShrinker = runResourceShrinking(options);
            return resourceShrinker;
        } catch (IOException | ParserConfigurationException | SAXException e) {
            throw new ResourceShrinkingFailedException(
                    "Failed running resource shrinking: " + e.getMessage(), e);
        }
    }

    private static ResourceShrinkerImpl runResourceShrinking(Options options)
            throws IOException, ParserConfigurationException, SAXException {
        validateInput(options.getInput());
        List<ResourceUsageRecorder> resourceUsageRecorders = new ArrayList<>();
        for (String dexInput : options.dex_inputs) {
            validateFileExists(dexInput);
            resourceUsageRecorders.add(
                    new DexUsageRecorder(
                            FileUtils.createZipFilesystem(Paths.get(dexInput)).getPath("")));
        }
        Path protoApk = Paths.get(options.getInput());
        Path protoApkOut = Paths.get(options.getOutput());
        FileSystem fileSystemProto = FileUtils.createZipFilesystem(protoApk);
        resourceUsageRecorders.add(new DexUsageRecorder(fileSystemProto.getPath("")));
        resourceUsageRecorders.add(
                new ProtoAndroidManifestUsageRecorder(
                        fileSystemProto.getPath(ANDROID_MANIFEST_XML)));
        for (String rawResource : options.getRawResources()) {
            resourceUsageRecorders.add(new ToolsAttributeUsageRecorder(Paths.get(rawResource)));
        }
        // If the apk contains a raw folder, find keep rules in there
        if (new ZipFile(options.getInput())
                .stream().anyMatch(zipEntry -> zipEntry.getName().startsWith("res/raw"))) {
            Path rawPath = fileSystemProto.getPath("res", "raw");
            resourceUsageRecorders.add(new ToolsAttributeUsageRecorder(rawPath));
        }
        ResourcesGatherer gatherer =
                new ProtoResourceTableGatherer(fileSystemProto.getPath(RESOURCES_PB));
        ProtoResourcesGraphBuilder res =
                new ProtoResourcesGraphBuilder(
                        fileSystemProto.getPath(RES_FOLDER), fileSystemProto.getPath(RESOURCES_PB));
        ResourceShrinkerImpl resourceShrinker =
                new ResourceShrinkerImpl(
                        List.of(gatherer),
                        null,
                        resourceUsageRecorders,
                        List.of(res),
                        options.usageLog != null
                                ? new FileReporter(Paths.get(options.usageLog).toFile())
                                : NoDebugReporter.INSTANCE,
                        false, // TODO(b/245721267): Add support for bundles
                        true);
        resourceShrinker.analyze();

        resourceShrinker.rewriteResourcesInApkFormat(
                protoApk.toFile(), protoApkOut.toFile(), LinkedResourcesFormat.PROTO);
        return resourceShrinker;
    }

    private static void validateInput(String input) throws IOException {
        ZipFile zipfile = new ZipFile(input);
        if (zipfile.getEntry(ANDROID_MANIFEST_XML) == null) {
            throw new ResourceShrinkingFailedException(
                    "Input must include " + ANDROID_MANIFEST_XML);
        }
        if (zipfile.getEntry(RESOURCES_PB) == null) {
            throw new ResourceShrinkingFailedException(
                    "Input must include "
                            + RESOURCES_PB
                            + ". Did you not convert the input apk"
                            + " to proto?");
        }
        if (zipfile.stream().noneMatch(zipEntry -> zipEntry.getName().startsWith(RES_FOLDER))) {
            throw new ResourceShrinkingFailedException(
                    "Input must include a " + RES_FOLDER + " folder");
        }
    }

    private static void validateFileExists(String file) {
        if (!Paths.get(file).toFile().exists()) {
            throw new RuntimeException("Can't find file: " + file);
        }
    }

    private static void validateOptions(Options options) {
        if (options.getInput() == null) {
            throw new ResourceShrinkingFailedException("No input given.");
        }
        if (options.getOutput() == null) {
            throw new ResourceShrinkingFailedException("No output destination given.");
        }
        validateFileExists(options.getInput());
        for (String rawResource : options.getRawResources()) {
            validateFileExists(rawResource);
        }
    }

    private static void printUsage() {
        PrintStream out = System.err;
        out.println("Usage:");
        out.println("  resourceshrinker ");
        out.println("    --input <input-file>, container with manifest, resources table and res");
        out.println("      folder. May contain dex.");
        out.println("    --dex_input <input-file> Container with dex files (only dex will be ");
        out.println("       handled if this contains other files. Several --dex_input arguments");
        out.println("       are supported");
        out.println("    --output <output-file>");
        out.println("    --raw_resource <xml-file or res directory>");
        out.println("      optional, more than one raw_resoures argument might be given");
        out.println("    --help prints this help message");
    }

    private static class ResourceShrinkingFailedException extends RuntimeException {
        public ResourceShrinkingFailedException(String message) {
            super(message);
        }

        public ResourceShrinkingFailedException(String message, Exception e) {
            super(message, e);
        }
    }
}
