// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;

import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;

/** Immutable command structure for an invocation of the {@link ExtractMarker} tool. */
@Keep
public class ExtractMarkerCommand {

  /** Builder for constructing a {@link ExtractMarkerCommand}. */
  @Keep
  public static class Builder {
    private boolean printHelp = false;
    private final List<Path> programFiles = new ArrayList<>();
    private final List<Pair<Origin, byte[]>> dexData = new ArrayList<>();
    private final List<Pair<Origin, byte[]>> cfData = new ArrayList<>();
    private MarkerInfoConsumer consumer;
    private DiagnosticsHandler handler;

    Builder(DiagnosticsHandler handler) {
      this.handler = handler;
    }

    public Builder setPrintHelp(boolean printHelp) {
      this.printHelp = printHelp;
      return this;
    }

    public boolean isPrintHelp() {
      return printHelp;
    }

    /**
     * Add program files to extract marker information from.
     *
     * <p>All program files supported by the input and output of D8/R8 can be passed here.
     */
    public Builder addProgramFiles(Path... programFiles) {
      return addProgramFiles(Arrays.asList(programFiles));
    }

    /**
     * Add program files to extract marker information from.
     *
     * <p>Each file added here will result in exactly one callback to {@link
     * MarkerInfoConsumer#acceptMarkerInfo}.
     *
     * <p>All program files supported by the input and output of D8/R8 can be passed here.
     */
    public Builder addProgramFiles(Collection<Path> programFiles) {
      this.programFiles.addAll(programFiles);
      return this;
    }

    /**
     * Add dex encoded bytes to extract marker information from.
     *
     * <p>Each data & origin pair added here will result in exactly one callback to {@link
     * MarkerInfoConsumer#acceptMarkerInfo}.
     */
    public Builder addDexProgramData(byte[] data, Origin origin) {
      dexData.add(new Pair<>(origin, data));
      return this;
    }

    /**
     * Add classfile encoded bytes to extract marker information from.
     *
     * <p>Each data & origin pair added here will result in exactly one callback to {@link
     * MarkerInfoConsumer#acceptMarkerInfo}.
     */
    public Builder addClassProgramData(byte[] data, Origin origin) {
      cfData.add(new Pair<>(origin, data));
      return this;
    }

    /** Set the callback to obtain the collected marker information. */
    public Builder setMarkerInfoConsumer(MarkerInfoConsumer consumer) {
      this.consumer = consumer;
      return this;
    }

    public ExtractMarkerCommand build() {
      // If printing versions ignore everything else.
      if (isPrintHelp()) {
        return new ExtractMarkerCommand(isPrintHelp());
      }
      return new ExtractMarkerCommand(handler, consumer, programFiles, dexData, cfData);
    }
  }

  static final String USAGE_MESSAGE =
      String.join(
          "\n",
          ImmutableList.of(
              "Usage: extractmarker [options] <input-files>",
              " where <input-files> are D8 supported input/output files and options are:",
              "  --help                  # Print this message."));

  public static Builder builder() {
    return builder(new DiagnosticsHandler() {});
  }

  public static Builder builder(DiagnosticsHandler handler) {
    return new Builder(handler);
  }

  public static Builder parse(String[] args) {
    Builder builder = builder();
    parse(args, builder);
    return builder;
  }

  private static void parse(String[] args, Builder builder) {
    for (int i = 0; i < args.length; i++) {
      String arg = args[i].trim();
      if (arg.equals("--help")) {
        builder.setPrintHelp(true);
      } else {
        if (arg.startsWith("--")) {
          throw new CompilationError("Unknown option: " + arg);
        }
        builder.addProgramFiles(Paths.get(arg));
      }
    }
  }

  private final boolean printHelp;
  private final DiagnosticsHandler handler;
  private final MarkerInfoConsumer consumer;
  private final List<Path> programFiles;
  private final List<Pair<Origin, byte[]>> dexData;
  private final List<Pair<Origin, byte[]>> cfData;

  private ExtractMarkerCommand(
      DiagnosticsHandler handler,
      MarkerInfoConsumer consumer,
      List<Path> programFiles,
      List<Pair<Origin, byte[]>> dexData,
      List<Pair<Origin, byte[]>> cfData) {
    this.printHelp = false;
    this.handler = handler;
    this.consumer = consumer;
    this.programFiles = programFiles;
    this.dexData = dexData;
    this.cfData = cfData;
  }

  private ExtractMarkerCommand(boolean printHelp) {
    this.printHelp = printHelp;
    handler = null;
    consumer = null;
    programFiles = null;
    dexData = null;
    cfData = null;
  }

  public boolean isPrintHelp() {
    return printHelp;
  }

  public MarkerInfoConsumer getMarkerInfoConsumer() {
    return consumer;
  }

  public DiagnosticsHandler getDiagnosticsHandler() {
    return handler;
  }

  public void forEachEntry(
      BiConsumer<Path, Origin> onProgramFile,
      BiConsumer<byte[], Origin> onDexData,
      BiConsumer<byte[], Origin> onCfData) {
    programFiles.forEach(path -> onProgramFile.accept(path, new PathOrigin(path)));
    dexData.forEach(pair -> onDexData.accept(pair.getSecond(), pair.getFirst()));
    cfData.forEach(pair -> onCfData.accept(pair.getSecond(), pair.getFirst()));
  }
}
