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

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.syntax.Type;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;

/** An {@link AndroidManifest} stamped with the correct package. */
@Immutable
public class StampedAndroidManifest extends AndroidManifest {

  StampedAndroidManifest(Artifact manifest, @Nullable String pkg, boolean exported) {
    super(manifest, pkg, exported);
  }

  @Override
  public StampedAndroidManifest stamp(AndroidDataContext dataContext) {
    // This manifest is already stamped
    return this;
  }

  /**
   * Gets the manifest artifact wrapped by this object.
   *
   * <p>The manifest is guaranteed to be stamped with the correct Android package.
   */
  @Override
  public Artifact getManifest() {
    return super.getManifest();
  }

  ProcessedAndroidManifest withProcessedManifest(Artifact processedManifest) {
    return new ProcessedAndroidManifest(processedManifest, getPackage(), isExported());
  }

  /** Creates an empty manifest stamped with the default Java package for this target. */
  public static StampedAndroidManifest createEmpty(RuleContext ruleContext, boolean exported) {
    return createEmpty(ruleContext, AndroidCommon.getJavaPackage(ruleContext), exported);
  }

  /** Creates an empty manifest stamped with a specified package. */
  public static StampedAndroidManifest createEmpty(
      ActionConstructionContext context, String pkg, boolean exported) {
    Artifact generatedManifest =
        context.getUniqueDirectoryArtifact("_generated", "AndroidManifest.xml");

    String contents =
        Joiner.on("\n")
            .join(
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
                "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"",
                "          package=\"" + pkg + "\">",
                "   <application>",
                "   </application>",
                "</manifest>");
    context.registerAction(
        FileWriteAction.create(context, generatedManifest, contents, /*makeExecutable=*/ false));
    return new StampedAndroidManifest(generatedManifest, pkg, exported);
  }

  public StampedAndroidManifest addMobileInstallStubApplication(RuleContext ruleContext)
      throws InterruptedException {

    Artifact stubManifest =
        ruleContext.getImplicitOutputArtifact(
            AndroidRuleClasses.MOBILE_INSTALL_STUB_APPLICATION_MANIFEST);
    Artifact stubData =
        ruleContext.getImplicitOutputArtifact(
            AndroidRuleClasses.MOBILE_INSTALL_STUB_APPLICATION_DATA);

    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(ruleContext.getExecutablePrerequisite("$stubify_manifest", Mode.HOST))
            .setProgressMessage("Injecting mobile install stub application")
            .setMnemonic("InjectMobileInstallStubApplication")
            .addInput(getManifest())
            .addOutput(stubManifest)
            .addOutput(stubData);
    CustomCommandLine.Builder commandLine =
        CustomCommandLine.builder()
            .add("--mode=mobile_install")
            .addExecPath("--input_manifest", getManifest())
            .addExecPath("--output_manifest", stubManifest)
            .addExecPath("--output_datafile", stubData);

    String overridePackage = getManifestValues(ruleContext).get("applicationId");
    if (overridePackage != null) {
      commandLine.add("--override_package", overridePackage);
    }

    builder.addCommandLine(commandLine.build());
    ruleContext.registerAction(builder.build(ruleContext));

    return new StampedAndroidManifest(stubManifest, getPackage(), isExported());
  }

  public static Map<String, String> getManifestValues(RuleContext context) {
    if (!context.attributes().isAttributeValueExplicitlySpecified("manifest_values")) {
      return ImmutableMap.of();
    }

    Map<String, String> manifestValues =
        new TreeMap<>(context.attributes().get("manifest_values", Type.STRING_DICT));

    for (String variable : manifestValues.keySet()) {
      manifestValues.put(
          variable, context.getExpander().expand("manifest_values", manifestValues.get(variable)));
    }
    return ImmutableMap.copyOf(manifestValues);
  }

  public StampedAndroidManifest createSplitManifest(
      RuleContext ruleContext, String splitName, boolean hasCode) {
    // aapt insists that manifests be called AndroidManifest.xml, even though they have to be
    // explicitly designated as manifests on the command line
    Artifact splitManifest =
        AndroidBinary.getDxArtifact(ruleContext, "split_" + splitName + "/AndroidManifest.xml");
    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(
                ruleContext.getExecutablePrerequisite("$build_split_manifest", Mode.HOST))
            .setProgressMessage("Creating manifest for split %s", splitName)
            .setMnemonic("AndroidBuildSplitManifest")
            .addInput(getManifest())
            .addOutput(splitManifest);
    CustomCommandLine.Builder commandLine =
        CustomCommandLine.builder()
            .addExecPath("--main_manifest", getManifest())
            .addExecPath("--split_manifest", splitManifest)
            .add("--split", splitName);
    if (hasCode) {
      commandLine.add("--hascode");
    } else {
      commandLine.add("--nohascode");
    }

    String overridePackage = getManifestValues(ruleContext).get("applicationId");

    if (overridePackage != null) {
      commandLine.add("--override_package", overridePackage);
    }

    builder.addCommandLine(commandLine.build());
    ruleContext.registerAction(builder.build(ruleContext));

    return new StampedAndroidManifest(splitManifest, getPackage(), isExported());
  }

  public AndroidManifestInfo toProvider() {
    return AndroidManifestInfo.of(getManifest(), getPackage(), isExported());
  }

  @Override
  public boolean equals(Object object) {
    return (object instanceof StampedAndroidManifest && super.equals(object));
  }
}
