/*
 * 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)));
        // 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);
        }
    }
}
