// 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.android;

import com.android.builder.core.VariantType;
import com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions;
import com.google.devtools.build.android.Converters.PathConverter;
import com.google.devtools.build.android.Converters.VariantTypeConverter;
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.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Action that processes resources for Databinding v2.
 */
public class AndroidDataBindingProcessingAction {

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

    @Option(
        name = "resource_root",
        defaultValue = "null",
        converter =  PathConverter.class,
        allowMultiple =  true,
        category = "input",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "Input resource root. A corresponding output resource root must be passed to "
            + "--output_resource_root. Multiple roots will be paired in the order they're passed.")
    public List<Path> resourceRoots;

    @Option(
        name = "output_resource_root",
        defaultValue =  "null",
        converter =  PathConverter.class,
        allowMultiple =  true,
        category = "input",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "The output resource root. A corresponding input resource root must be passed to "
            + "--resource_root. Multiple roots will be paired in the order they're passed.")
    public List<Path> outputResourceRoots;

    @Option(
        name = "packageType",
        defaultValue = "DEFAULT",
        converter = VariantTypeConverter.class,
        category = "config",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help =
            "Variant configuration type for packaging the resources."
                + " Acceptable values DEFAULT, LIBRARY, ANDROID_TEST, UNIT_TEST")
    public VariantType packageType;

    @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 = "appId",
        defaultValue = "null",
        category = "config",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = {OptionEffectTag.UNKNOWN},
        help = "The java package for the app.")
    public String appId;
  }

  public static void main(String[] args) throws IOException {

    OptionsParser optionsParser =
        OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
    optionsParser.enableParamsFileSupport(
        new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()));
    optionsParser.parseAndExitUponError(args);
    Options options = optionsParser.getOptions(Options.class);

    if (options.dataBindingInfoOut == null) {
      throw new IllegalArgumentException("--dataBindingInfoOut is required");
    }

    if (options.appId == null) {
      throw new IllegalArgumentException("--appId is required");
    }

    List<Path> resourceRoots = options.resourceRoots == null
        ? Collections.emptyList()
        : options.resourceRoots;
    List<Path> outputResourceRoots = options.outputResourceRoots == null
        ? Collections.emptyList()
        : options.outputResourceRoots;

    if (resourceRoots.size() != outputResourceRoots.size()) {
      throw new IllegalArgumentException("--resource_root and --output_resource_root must be "
          + "specified the same number of times");
    }

    try (ScopedTemporaryDirectory dataBindingInfoOutDir =
        new ScopedTemporaryDirectory("android_data_binding_layout_info_tmp")) {

      // 1. Process databinding resources for each source root.
      for (int i = 0; i < resourceRoots.size(); i++) {

        Path resourceRoot = resourceRoots.get(i);
        Path outputResourceRoot = outputResourceRoots.get(i);
        AndroidResourceProcessor.processDataBindings(
            outputResourceRoot,
            resourceRoot,
            dataBindingInfoOutDir.getPath(),
            options.appId,
            /* shouldZipDataBindingInfo= */ false);
      }

      // 2. Zip all the layout info files into one zip file.
      try (ZipOutputStream layoutInfoZip =
            new ZipOutputStream(Files.newOutputStream(options.dataBindingInfoOut));
          Stream<Path> layoutInfos = Files.list(dataBindingInfoOutDir.getPath())) {

        for (Path layoutInfo : (Iterable<Path>) layoutInfos::iterator) {
          ZipEntry zipEntry = new ZipEntry(layoutInfo.getFileName().toString());
          layoutInfoZip.putNextEntry(zipEntry);
          Files.copy(layoutInfo, layoutInfoZip);
          layoutInfoZip.closeEntry();
        }
      }
    }
  }
}
