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

import com.android.dx.cf.direct.DirectClassFile;
import com.android.dx.cf.direct.StdAttributeFactory;
import com.android.dx.command.dexer.DxContext;
import com.android.dx.dex.DexOptions;
import com.android.dx.dex.cf.CfOptions;
import com.android.dx.dex.cf.CfTranslator;
import com.android.dx.dex.code.PositionList;
import com.android.dx.dex.file.ClassDefItem;
import com.android.dx.dex.file.DexFile;
import com.android.dx.util.ByteArray;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.io.ByteStreams;
import com.google.devtools.common.options.Converter;
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.OptionsParsingException;
import java.io.PrintStream;
import java.lang.reflect.Field;

/**
 * Common helper class that encodes Java classes into {@link DexFile}s.
 */
class Dexing {

  static final PrintStream nullout = new PrintStream(ByteStreams.nullOutputStream());

  /**
   * Parser for positions options based on the integer field names in {@link PositionList}.
   */
  public static class PositionGranularityConverter implements Converter<Integer> {
    @Override
    public Integer convert(String input) throws OptionsParsingException {
      for (Field field : PositionList.class.getFields()) {
        if (field.getName().equalsIgnoreCase(input)) {
          try {
            return field.getInt(null);
          } catch (RuntimeException | IllegalAccessException e) {
            throw new OptionsParsingException("Can't parse positions option", input, e);
          }
        }
      }
      throw new OptionsParsingException("Unknown positions option", input);
    }

    @Override
    public String getTypeDescription() {
      return "One of the options from dx's --positions flag";
    }
  }

  /**
   * Common command line options for use with {@link Dexing}.
   */
  public static class DexingOptions extends OptionsBase {

    @Option(
      name = "locals",
      defaultValue = "true", // dx's default
      category = "semantics",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      allowMultiple = false,
      help = "Whether to include local variable tables (useful for debugging)."
    )
    public boolean localInfo;

    @Option(
      name = "optimize",
      defaultValue = "true", // dx's default
      category = "semantics",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      allowMultiple = false,
      help = "Whether to do SSA/register optimization."
    )
    public boolean optimize;

    @Option(
      name = "positions",
      defaultValue = "lines", // dx's default
      category = "semantics",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      allowMultiple = false,
      converter = PositionGranularityConverter.class,
      help = "How densely to emit line number information."
    )
    // Note this field must be initialized (usually done by an options parser) since the implicit
    // initial value 0 is not valid.
    public int positionInfo;

    @Option(
      name = "warning",
      defaultValue = "true", // dx's default
      category = "misc",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      allowMultiple = false,
      help = "Whether to print warnings."
    )
    public boolean printWarnings;

    public CfOptions toCfOptions(DxContext context) {
      CfOptions result = new CfOptions();
      result.localInfo = this.localInfo;
      result.optimize = this.optimize;
      result.warn = printWarnings ? context.err : Dexing.nullout;
      // Use dx's defaults
      result.optimizeListFile = null;
      result.dontOptimizeListFile = null;
      result.positionInfo = positionInfo;
      result.strictNameCheck = true;
      result.statistics = false; // we're not supporting statistics anyways
      return result;
    }

    public DexOptions toDexOptions() {
      DexOptions result = new DexOptions();
      result.forceJumbo = false; // dx's default
      return result;
    }
  }

  /**
   * Class file and possible dexing options, to look up dexing results in caches.
   */
  @AutoValue
  abstract static class DexingKey {
    static DexingKey create(
        boolean localInfo, boolean optimize, int positionInfo, byte[] classfileContent) {
      // TODO(bazel-team): Maybe we can use a minimal collision hash instead of full content
      return new AutoValue_Dexing_DexingKey(localInfo, optimize, positionInfo, classfileContent);
    }

    /** Returns whether {@link CfOptions#localInfo local variable information} is included. */
    abstract boolean localInfo();

    /** Returns whether {@link CfOptions#optimize SSA/register optimization} is performed. */
    abstract boolean optimize();

    /** Returns how much line number information is emitted as a {@link PositionList} constant. */
    abstract int positionInfo();

    /** Returns the class file to dex, <b>not</b> the dexed class. Don't modify the return value! */
    @SuppressWarnings("mutable") abstract byte[] classfileContent();
  }

  private final DxContext context;
  private final DexOptions dexOptions;
  private final CfOptions cfOptions;

  public Dexing(DexingOptions options) {
    this(new DxContext(), options);
  }

  public Dexing(DxContext context, DexingOptions options) {
    this(context, options.toDexOptions(), options.toCfOptions(context));
  }

  @VisibleForTesting
  Dexing(DxContext context, DexOptions dexOptions, CfOptions cfOptions) {
    this.context = context;
    this.dexOptions = dexOptions;
    this.cfOptions = cfOptions;
  }

  public static DirectClassFile parseClassFile(byte[] classfile, String classfilePath) {
    DirectClassFile result = new DirectClassFile(
        new ByteArray(classfile), classfilePath, /*strictParse*/ false);
    result.setAttributeFactory(StdAttributeFactory.THE_ONE);
    result.getMagic(); // triggers the parsing
    return result;
  }

  public DexFile newDexFile() {
    return new DexFile(dexOptions);
  }

  public ClassDefItem addToDexFile(DexFile dest, DirectClassFile classFile) {
    ClassDefItem result = CfTranslator.translate(
        context,
        classFile,
        (byte[]) null /*ignored*/,
        cfOptions,
        dest.getDexOptions(),
        dest);
    dest.add(result);
    return result;
  }

  public DexingKey getDexingKey(byte[] classfile) {
    return DexingKey.create(
        cfOptions.localInfo, cfOptions.optimize, cfOptions.positionInfo, classfile);
  }
}
