// Copyright (c) 2016, 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.naming;

import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.MemberNaming.Signature.SignatureKind;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * Stores renaming information for a member.
 * <p>
 * This includes the signature, the original name and inlining range information.
 */
public class MemberNaming {

  private static final int UNDEFINED_START_NUMBER = -1;

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof MemberNaming)) {
      return false;
    }

    MemberNaming that = (MemberNaming) o;
    return signature.equals(that.signature)
        && renamedSignature.equals(that.renamedSignature)
        && topLevelRange.equals(that.topLevelRange)
        && inlineInformation.equals(that.inlineInformation);
  }

  @Override
  public int hashCode() {
    int result = signature.hashCode();
    result = 31 * result + renamedSignature.hashCode();
    result = 31 * result + inlineInformation.hashCode();
    result = 31 * result + topLevelRange.hashCode();
    return result;
  }

  /**
   * Original signature of the member
   */
  final Signature signature;
  /**
   * Renamed signature where the name (but not the types) have been renamed.
   */
  final Signature renamedSignature;
  public final List<InlineInformation> inlineInformation = new LinkedList<>();
  public final Range topLevelRange;

  private int collapsedStartLineNumber = UNDEFINED_START_NUMBER;
  private int originalStartLineNumber = UNDEFINED_START_NUMBER;

  MemberNaming(Signature signature, String renamedName, Range inlinedLineRange) {
    this.signature = signature;
    this.renamedSignature = signature.asRenamed(renamedName);
    topLevelRange = inlinedLineRange == null ? fakeZeroRange : inlinedLineRange;
  }

  public void addInliningRange(Range inlinedRange, Signature signature, Range originalRange) {
    inlineInformation.add(new InlineInformation(inlinedRange, originalRange, signature));
  }

  public List<Range> getInlineRanges() {
    List<Range> inlineRanges = new ArrayList<>();
    for (InlineInformation information : inlineInformation) {
      if (information.isActualInlining()) {
        inlineRanges.add(information.inlinedRange);
      }
    }
    return inlineRanges;
  }

  public Signature getOriginalSignature() {
    return signature;
  }

  public String getRenamedName() {
    return renamedSignature.name;
  }

  public void setCollapsedStartLineNumber(int value) {
    assert collapsedStartLineNumber == UNDEFINED_START_NUMBER;
    collapsedStartLineNumber = value;
  }

  public boolean isMethodNaming() {
    return signature.kind() == SignatureKind.METHOD;
  }

  private int getCollapsedStartLineNumber() {
    return collapsedStartLineNumber;
  }

  protected void write(Writer writer, boolean collapseRanges, boolean indent) throws IOException {
    if (indent) {
      writer.append("    ");
    }
    int rangeCounter =
        collapseRanges ? getCollapsedStartLineNumber() : InlineInformation.DO_NOT_COLLAPSE;
    // Avoid printing the range information if there was none in the original file.
    if (topLevelRange != fakeZeroRange || rangeCounter != UNDEFINED_START_NUMBER) {
      if (collapseRanges) {
        // Skip ranges for methods that are used only once, as they do not have debug information.
        if (rangeCounter != UNDEFINED_START_NUMBER) {
          String rangeString = Integer.toString(rangeCounter);
          writer.append(rangeString).append(":").append(rangeString).append(":");
        } else {
          rangeCounter = 0;
        }
      } else {
        writer.append(topLevelRange.toString());
        writer.append(':');
      }
    } else {
      // We might end up in a case where we have no line information for the top entry but still
      // have inline ranges. Just to be sure, set rangeCounter to a useful value.
      if (collapseRanges) {
        rangeCounter = 0;
      }
    }
    signature.write(writer);
    if (originalStartLineNumber != UNDEFINED_START_NUMBER) {
      // If we have original line number information, print it here.
      String originalSourceLineString = Integer.toString(originalStartLineNumber);
      writer.append(':')
          .append(originalSourceLineString)
          .append(':')
          .append(originalSourceLineString);
    }
    writer.append(" -> ");
    writer.append(renamedSignature.name);
    writer.append("\n");
    for (InlineInformation information : inlineInformation) {
      assert !collapseRanges || rangeCounter >= 0;
      if (collapseRanges && information.isActualInlining()) {
        rangeCounter++;
      }
      information.write(writer, rangeCounter, indent);
    }
  }

  @Override
  public String toString() {
    try {
      StringWriter writer = new StringWriter();
      write(writer, false, false);
      return writer.toString();
    } catch (IOException e) {
      return e.toString();
    }
  }

  public void setOriginalStartLineNumber(int originalStartLineNumber) {
    assert this.originalStartLineNumber == UNDEFINED_START_NUMBER;
    this.originalStartLineNumber = originalStartLineNumber;
  }

  public abstract static class Signature {

    public final String name;

    protected Signature(String name) {
      this.name = name;
    }

    abstract Signature asRenamed(String renamedName);

    abstract public SignatureKind kind();

    @Override
    abstract public boolean equals(Object o);

    @Override
    abstract public int hashCode();

    abstract void write(Writer builder) throws IOException;

    @Override
    public String toString() {
      try {
        StringWriter writer = new StringWriter();
        write(writer);
        return writer.toString();
      } catch (IOException e) {
        return e.toString();
      }
    }

    enum SignatureKind {
      METHOD,
      FIELD
    }
  }

  public static class FieldSignature extends Signature {

    public final String type;

    public FieldSignature(String name, String type) {
      super(name);
      this.type = type;
    }

    public static FieldSignature fromDexField(DexField field) {
      return new FieldSignature(field.name.toSourceString(),
          field.type.toSourceString());
    }

    @Override
    Signature asRenamed(String renamedName) {
      return new FieldSignature(renamedName, type);
    }

    @Override
    public SignatureKind kind() {
      return SignatureKind.FIELD;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof FieldSignature)) {
        return false;
      }
      FieldSignature that = (FieldSignature) o;
      return name.equals(that.name) && type.equals(that.type);
    }

    @Override
    public int hashCode() {
      return name.hashCode() * 31 + type.hashCode();
    }

    @Override
    public String toString() {
      return type + " " + name;
    }

    @Override
    void write(Writer writer) throws IOException {
      writer.append(type);
      writer.append(' ');
      writer.append(name);
    }
  }

  public static class MethodSignature extends Signature {

    public final String type;
    public final String[] parameters;

    public MethodSignature(String name, String type, String[] parameters) {
      super(name);
      this.type = type;
      this.parameters = parameters;
    }

    public static MethodSignature fromDexMethod(DexMethod method) {
      String[] paramNames = new String[method.getArity()];
      DexType[] values = method.proto.parameters.values;
      for (int i = 0; i < values.length; i++) {
        paramNames[i] = values[i].toSourceString();
      }
      return new MethodSignature(method.name.toSourceString(),
          method.proto.returnType.toSourceString(), paramNames);
    }

    @Override
    Signature asRenamed(String renamedName) {
      return new MethodSignature(renamedName, type, parameters);
    }

    @Override
    public SignatureKind kind() {
      return SignatureKind.METHOD;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof MethodSignature)) {
        return false;
      }

      MethodSignature that = (MethodSignature) o;
      return type.equals(that.type)
          && name.equals(that.name)
          && Arrays.equals(parameters, that.parameters);
    }

    @Override
    public int hashCode() {
      return (type.hashCode() * 17
          + name.hashCode()) * 31
          + Arrays.hashCode(parameters);
    }

    @Override
    void write(Writer writer) throws IOException {
      writer.append(type)
          .append(' ')
          .append(name)
          .append('(');
      for (int i = 0; i < parameters.length; i++) {
        writer.append(parameters[i]);
        if (i < parameters.length - 1) {
          writer.append(',');
        }
      }
      writer.append(')');
    }
  }

  public class InlineInformation {
    static final int DO_NOT_COLLAPSE = -1;

    public final Range inlinedRange;
    public final Range originalRange;
    public final Signature signature;

    public InlineInformation(Range inlinedRange, Range originalRange, Signature signature) {
      this.inlinedRange = inlinedRange;
      this.originalRange = originalRange;
      this.signature = signature;
    }

    public boolean isActualInlining() {
      return !(originalRange instanceof SingleLineRange);
    }

    public void write(Writer writer, int collapsedRange, boolean indent) throws IOException {
      if (indent) {
        writer.append("    ");
      }
      if (collapsedRange == DO_NOT_COLLAPSE) {
        writer.append(inlinedRange.toString());
      } else {
        writer.append(Range.toCollapsedString(collapsedRange));
      }
      writer.append(":");
      signature.write(writer);
      if (originalRange != null) {
        writer.append(':')
            .append(originalRange.toString());
      }
      writer.append(" -> ")
          .append(renamedSignature.name);
      writer.append("\n");
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof InlineInformation)) {
        return false;
      }

      InlineInformation that = (InlineInformation) o;

      return inlinedRange.equals(that.inlinedRange)
          && ((originalRange == null && that.originalRange == null)
              || originalRange.equals(that.originalRange))
          && signature.equals(that.signature);

    }

    @Override
    public int hashCode() {
      int result = inlinedRange.hashCode();
      result = 31 * result + originalRange.hashCode();
      result = 31 * result + signature.hashCode();
      return result;
    }
  }

  /**
   * Represents a linenumber range.
   */
  public static class Range {

    public final int from;
    public final int to;

    Range(int from, int to) {
      this.from = from;
      this.to = to;
    }

    public boolean contains(int value) {
      return value >= from && value <= to;
    }

    public boolean isSingle() {
      return false;
    }

    @Override
    public String toString() {
      return from + ":" + to;
    }

    public static String toCollapsedString(int value) {
      return value + ":" + value;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof Range)) {
        return false;
      }

      Range range = (Range) o;
      return from == range.from && to == range.to;
    }

    @Override
    public int hashCode() {
      int result = from;
      result = 31 * result + to;
      return result;
    }

  }

  /**
   * Represents a single linenumber range (':' followed by a signle number), which
   * is different semantically from a normal range that has the same from and to.
   */
  public static class SingleLineRange extends Range {
    public SingleLineRange(int fromAndTo) {
      super(fromAndTo, fromAndTo);
    }

    @Override
    public boolean isSingle() {
      return true;
    }

    @Override
    public String toString() {
      return Integer.toString(from);
    }
  }

  public final static Range fakeZeroRange = new Range(0, 0);
}
