// Copyright 2016 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 com.google.devtools.build.android;

import com.android.builder.core.VariantConfiguration;
import com.android.builder.core.VariantType;
import com.android.ide.common.internal.PngCruncher;
import com.android.ide.common.internal.PngException;
import com.android.utils.StdLogger;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.google.devtools.build.android.AndroidDataMerger.MergeConflictException;
import com.google.devtools.build.android.AndroidResourceMerger.MergingException;
import com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions;
import com.google.devtools.build.android.Converters.ExistingPathConverter;
import com.google.devtools.build.android.Converters.PathConverter;
import com.google.devtools.build.android.Converters.SerializedAndroidDataConverter;
import com.google.devtools.build.android.Converters.SerializedAndroidDataListConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Provides an entry point for the resource merging action. After merging, this action generates the
 * R.class files required to compile the rest of the java sources.
 *
 * <p>This action only generates the class jar. The R source jar is generated by AAPT at a later
 * time and off of the critical path, by {@link AndroidResourceValidatorAction}. That way, the
 * source will contain javadocs derived from comments in the .xml files. Ideally users wouldn't use
 * the javadoc, but instead generate documentation directly from the source .xml files.
 */
public class AndroidResourceMergingAction {

  private static final StdLogger stdLogger = new StdLogger(StdLogger.Level.WARNING);

  private static final Logger logger =
      Logger.getLogger(AndroidResourceMergingAction.class.getName());

  /** Flag specifications for this action. */
  public static final class Options extends OptionsBase {

    @Option(
      name = "primaryData",
      defaultValue = "null",
      converter = SerializedAndroidDataConverter.class,
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "The directory containing the primary resource directory. The contents will override"
              + " the contents of any other resource directories during merging."
              + " The expected format is "
              + SerializedAndroidData.EXPECTED_FORMAT
    )
    public SerializedAndroidData primaryData;

    @Option(
      name = "primaryManifest",
      defaultValue = "null",
      converter = ExistingPathConverter.class,
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path to primary resource's manifest file."
    )
    public Path primaryManifest;

    @Option(
      name = "data",
      defaultValue = "",
      converter = SerializedAndroidDataListConverter.class,
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Transitive Data dependencies. These values will be used if not defined in the "
              + "primary resources. The expected format is "
              + SerializedAndroidData.EXPECTED_FORMAT
              + "[&...]"
    )
    public List<SerializedAndroidData> transitiveData;

    @Option(
      name = "directData",
      defaultValue = "",
      converter = SerializedAndroidDataListConverter.class,
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Direct Data dependencies. These values will be used if not defined in the "
              + "primary resources. The expected format is "
              + SerializedAndroidData.EXPECTED_FORMAT
              + "[&...]"
    )
    public List<SerializedAndroidData> directData;

    @Option(
      name = "resourcesOutput",
      defaultValue = "null",
      converter = PathConverter.class,
      category = "output",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path to the write merged resources archive."
    )
    public Path resourcesOutput;

    @Option(
      name = "classJarOutput",
      defaultValue = "null",
      converter = PathConverter.class,
      category = "output",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path for the generated java class jar."
    )
    public Path classJarOutput;

    @Option(
      name = "manifestOutput",
      defaultValue = "null",
      converter = PathConverter.class,
      category = "output",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path for the output processed AndroidManifest.xml."
    )
    public Path manifestOutput;

    @Option(
      name = "packageForR",
      defaultValue = "null",
      category = "config",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Custom java package to generate the R symbols files."
    )
    public String packageForR;

    @Option(
      name = "symbolsBinOut",
      defaultValue = "null",
      converter = PathConverter.class,
      category = "config",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path to write the merged symbols binary."
    )
    public Path symbolsBinOut;

    @Option(
      name = "dataBindingInfoOut",
      defaultValue = "null",
      converter = PathConverter.class,
      category = "output",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "Path to where data binding's layout info output should be written."
    )
    public Path dataBindingInfoOut;

    @Option(
      name = "throwOnResourceConflict",
      defaultValue = "false",
      category = "config",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "If passed, resource merge conflicts will be treated as errors instead of warnings"
    )
    public boolean throwOnResourceConflict;

    @Option(
      name = "targetLabel",
      defaultValue = "null",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "A label to add to the output jar's manifest as 'Target-Label'"
    )
    public String targetLabel;

    @Option(
      name = "injectingRuleKind",
      defaultValue = "null",
      category = "input",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help = "A string to add to the output jar's manifest as 'Injecting-Rule-Kind'"
    )
    public String injectingRuleKind;
  }

  public static void main(String[] args) throws Exception {
    final Stopwatch timer = Stopwatch.createStarted();
    OptionsParser optionsParser =
        OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
    optionsParser.enableParamsFileSupport(
        new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()));
    optionsParser.parseAndExitUponError(args);
    AaptConfigOptions aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class);
    Options options = optionsParser.getOptions(Options.class);

    Preconditions.checkNotNull(options.primaryData);
    Preconditions.checkNotNull(options.primaryManifest);

    try (ScopedTemporaryDirectory scopedTmp =
            new ScopedTemporaryDirectory("android_resource_merge_tmp");
        ExecutorServiceCloser executorService = ExecutorServiceCloser.createWithFixedPoolOf(15)) {
      Path tmp = scopedTmp.getPath();
      Path mergedAssets = tmp.resolve("merged_assets");
      Path mergedResources = tmp.resolve("merged_resources");
      Path generatedSources = tmp.resolve("generated_resources");
      Path processedManifest = tmp.resolve("manifest-processed/AndroidManifest.xml");

      logger.fine(String.format("Setup finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));

      VariantType packageType = VariantType.LIBRARY;
      String packageForR = options.packageForR;
      if (packageForR == null) {
        packageForR =
            Strings.nullToEmpty(
                VariantConfiguration.getManifestPackage(options.primaryManifest.toFile()));
      }
      AndroidResourceClassWriter resourceClassWriter =
          AndroidResourceClassWriter.createWith(
              aaptConfigOptions.androidJar, generatedSources, packageForR);
      resourceClassWriter.setIncludeClassFile(true);
      resourceClassWriter.setIncludeJavaFile(false);

      final MergedAndroidData mergedData =
          AndroidResourceMerger.mergeData(
              options.primaryData,
              options.primaryManifest,
              options.directData,
              options.transitiveData,
              mergedResources,
              mergedAssets,
              new StubPngCruncher(),
              packageType,
              options.symbolsBinOut,
              resourceClassWriter,
              options.throwOnResourceConflict,
              executorService);

      logger.fine(String.format("Merging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));

      // Until enough users with manifest placeholders migrate to the new manifest merger,
      // we need to replace ${applicationId} and ${packageName} with options.packageForR to make
      // the manifests compatible with the old manifest merger.
      if (options.manifestOutput != null) {
        MergedAndroidData processedData =
            AndroidManifestProcessor.with(stdLogger)
                .processManifest(
                    packageType,
                    options.packageForR,
                    /* applicationId= */ null,
                    /* versionCode= */ -1,
                    /* versionName= */ null,
                    mergedData,
                    processedManifest);
        AndroidResourceOutputs.copyManifestToOutput(processedData, options.manifestOutput);
      }

      if (options.classJarOutput != null) {
        AndroidResourceOutputs.createClassJar(
            generatedSources,
            options.classJarOutput,
            options.targetLabel,
            options.injectingRuleKind);
        logger.fine(
            String.format(
                "Create classJar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
      }

      if (options.resourcesOutput != null) {
        Path resourcesDir =
            AndroidResourceProcessor.processDataBindings(
                tmp.resolve("res_no_binding"),
                mergedData.getResourceDir(),
                options.dataBindingInfoOut,
                packageType,
                options.packageForR,
                options.primaryManifest,
                true);

        // For now, try compressing the library resources that we pass to the validator. This takes
        // extra CPU resources to pack and unpack (~2x), but can reduce the zip size (~4x).
        ResourcesZip.from(resourcesDir, mergedData.getAssetDir())
            .writeTo(options.resourcesOutput, /* compress= */ true);
        logger.fine(
            String.format(
                "Create resources.zip finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
      }
    } catch (MergeConflictException e) {
      logger.log(Level.SEVERE, e.getMessage());
      System.exit(1);
    } catch (MergingException e) {
      logger.log(Level.SEVERE, "Error during merging resources", e);
      throw e;
    } catch (AndroidManifestProcessor.ManifestProcessingException e) {
      System.exit(1);
    } catch (Exception e) {
      logger.log(Level.SEVERE, "Unexpected", e);
      throw e;
    }
    logger.fine(String.format("Resources merged in %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
  }

  /**
   * The merged {@link Options#resourcesOutput} is only used for validation and not for running
   * (unlike the final APK), so the image files do not need to be the true image files. We only need
   * the filenames to be the same.
   *
   * <p>Thus, we only create empty files for PNGs (convenient with a custom PngCruncher object).
   * This does miss out on other image files like .webp.
   */
  private static final class StubPngCruncher implements PngCruncher {

    @Override
    public void crunchPng(int key, File from, File to) throws PngException {
      try {
        Files.touch(to);
      } catch (IOException e) {
        throw new PngException(e);
      }
    }

    @Override
    public int start() {
      return 0;
    }

    @Override
    public void end(int key) {}
  }
}
