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

import com.android.tools.r8.DiagnosticsHandler;
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.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
import com.android.tools.r8.naming.MemberNaming.Signature.SignatureKind;
import com.android.tools.r8.naming.mappinginformation.MappingInformation;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThrowingConsumer;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Stores name information for a class.
 * <p>
 * The main differences of this against {@link ClassNamingForNameMapper} are:
 *   1) field and method mappings are maintained and searched separately for faster lookup;
 *   2) similar to the relation between {@link ClassNameMapper} and {@link SeedMapper}, this one
 *   uses original {@link Signature} as a key to look up {@link MemberNaming},
 *   whereas {@link ClassNamingForNameMapper} uses renamed {@link Signature} as a key; and thus
 *   3) logic of {@link #lookup} and {@link #lookupByOriginalSignature} are inverted; and
 *   4) {@link #lookupByOriginalItem}'s are introduced for lightweight lookup.
 */
public class ClassNamingForMapApplier implements ClassNaming {

  public static class Builder extends ClassNaming.Builder {

    private final String originalName;
    private final String renamedName;
    private final Position position;
    private final Reporter reporter;
    private final Map<MethodSignature, List<MemberNaming>> qualifiedMethodMembers = new HashMap<>();
    private final Map<MethodSignature, MemberNaming> methodMembers = new HashMap<>();
    private final Map<FieldSignature, MemberNaming> fieldMembers = new HashMap<>();

    private Builder(String renamedName, String originalName, Position position, Reporter reporter) {
      this.originalName = originalName;
      this.renamedName = renamedName;
      this.position = position;
      this.reporter = reporter;
    }

    @Override
    public ClassNaming.Builder addMemberEntry(MemberNaming entry) {
      // Unlike {@link ClassNamingForNameMapper.Builder#addMemberEntry},
      // the key is original signature.
      if (entry.isMethodNaming()) {
        MethodSignature signature = (MethodSignature) entry.getOriginalSignature();
        if (signature.isQualified()) {
          qualifiedMethodMembers.computeIfAbsent(signature, k -> new ArrayList<>(2)).add(entry);
        } else if (methodMembers.put(signature, entry) != null) {
          reporter.error(
              ProguardMapError.duplicateSourceMember(
                  signature.toString(), this.originalName, entry.position));
        }
      } else {
        FieldSignature signature = (FieldSignature) entry.getOriginalSignature();
        if (!signature.isQualified() && fieldMembers.put(signature, entry) != null) {
          reporter.error(
              ProguardMapError.duplicateSourceMember(
                  signature.toString(), this.originalName, entry.position));
        }
      }
      return this;
    }

    @Override
    public ClassNaming.Builder addMappingInformation(MappingInformation mappingInformation) {
      // Intentionally kept empty until we support additional information with -applymapping.
      return this;
    }

    @Override
    public ClassNaming.Builder addMappingInformation(
        MappingInformation mappingInformation,
        DiagnosticsHandler diagnosticsHandler,
        int lineNumber) {
      // Intentionally kept empty until we support additional information with -applymapping.
      return this;
    }

    @Override
    public ClassNamingForMapApplier build() {
      return new ClassNamingForMapApplier(
          renamedName, originalName, position, qualifiedMethodMembers, methodMembers, fieldMembers);
    }

    @Override
    /** No-op */
    public void addMappedRange(
        Range obfuscatedRange,
        MemberNaming.MethodSignature originalSignature,
        Object originalRange,
        String obfuscatedName) {}
  }

  static Builder builder(
      String renamedName, String originalName, Position position, Reporter reporter) {
    return new Builder(renamedName, originalName, position, reporter);
  }

  private final String originalName;
  final String renamedName;
  final Position position;

  private final ImmutableMap<MethodSignature, List<MemberNaming>> qualifiedMethodMembers;
  private final ImmutableMap<MethodSignature, MemberNaming> methodMembers;
  private final ImmutableMap<FieldSignature, MemberNaming> fieldMembers;

  // Constructor to help chaining {@link ClassNamingForMapApplier} according to class hierarchy.
  ClassNamingForMapApplier(ClassNamingForMapApplier proxy) {
    this(
        proxy.renamedName,
        proxy.originalName,
        proxy.position,
        proxy.qualifiedMethodMembers,
        proxy.methodMembers,
        proxy.fieldMembers);
  }

  private ClassNamingForMapApplier(
      String renamedName,
      String originalName,
      Position position,
      Map<MethodSignature, List<MemberNaming>> qualifiedMethodMembers,
      Map<MethodSignature, MemberNaming> methodMembers,
      Map<FieldSignature, MemberNaming> fieldMembers) {
    this.renamedName = renamedName;
    this.originalName = originalName;
    this.position = position;
    this.qualifiedMethodMembers = ImmutableMap.copyOf(qualifiedMethodMembers);
    this.methodMembers = ImmutableMap.copyOf(methodMembers);
    this.fieldMembers = ImmutableMap.copyOf(fieldMembers);
  }

  public ImmutableMap<MethodSignature, List<MemberNaming>> getQualifiedMethodMembers() {
    return qualifiedMethodMembers;
  }

  @Override
  public <T extends Throwable> void forAllMemberNaming(
      ThrowingConsumer<MemberNaming, T> consumer) throws T {
    forAllFieldNaming(consumer);
    forAllMethodNaming(consumer);
  }

  @Override
  public <T extends Throwable> void forAllFieldNaming(
      ThrowingConsumer<MemberNaming, T> consumer) throws T {
    for (MemberNaming naming : fieldMembers.values()) {
      consumer.accept(naming);
    }
  }

  @Override
  public <T extends Throwable> void forAllMethodNaming(
      ThrowingConsumer<MemberNaming, T> consumer) throws T {
    for (MemberNaming naming : methodMembers.values()) {
      consumer.accept(naming);
    }
  }

  @Override
  public MemberNaming lookup(Signature renamedSignature) {
    // As the key is inverted, this looks a lot like
    //   {@link ClassNamingForNameMapper#lookupByOriginalSignature}.
    if (renamedSignature.kind() == SignatureKind.METHOD) {
      for (MemberNaming memberNaming : methodMembers.values()) {
        if (memberNaming.getRenamedSignature().equals(renamedSignature)) {
          return memberNaming;
        }
      }
      return null;
    } else {
      assert renamedSignature.kind() == SignatureKind.FIELD;
      for (MemberNaming memberNaming : fieldMembers.values()) {
        if (memberNaming.getRenamedSignature().equals(renamedSignature)) {
          return memberNaming;
        }
      }
      return null;
    }
  }

  @Override
  public MemberNaming lookupByOriginalSignature(Signature original) {
    // As the key is inverted, this looks a lot like {@link ClassNamingForNameMapper#lookup}.
    if (original.kind() == SignatureKind.METHOD) {
      return methodMembers.get(original);
    } else {
      assert original.kind() == SignatureKind.FIELD;
      return fieldMembers.get(original);
    }
  }

  MemberNaming lookupByOriginalItem(DexField field) {
    for (Map.Entry<FieldSignature, MemberNaming> entry : fieldMembers.entrySet()) {
      FieldSignature signature = entry.getKey();
      if (signature.name.equals(field.name.toSourceString())
          && signature.type.equals(field.type.toSourceString())) {
        return entry.getValue();
      }
    }
    return null;
  }

  protected MemberNaming lookupByOriginalItem(DexMethod method) {
    for (Map.Entry<MethodSignature, MemberNaming> entry : methodMembers.entrySet()) {
      MethodSignature signature = entry.getKey();
      if (signature.name.equals(method.name.toSourceString())
          && signature.type.equals(method.proto.returnType.toSourceString())
          && Arrays.equals(signature.parameters,
              Arrays.stream(method.proto.parameters.values)
                  .map(DexType::toSourceString).toArray(String[]::new))) {
        return entry.getValue();
      }
    }
    return null;
  }

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

    ClassNamingForMapApplier that = (ClassNamingForMapApplier) o;

    return originalName.equals(that.originalName)
        && renamedName.equals(that.renamedName)
        && qualifiedMethodMembers.equals(that.qualifiedMethodMembers)
        && methodMembers.equals(that.methodMembers)
        && fieldMembers.equals(that.fieldMembers);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(
        originalName, renamedName, qualifiedMethodMembers, methodMembers, fieldMembers);
  }
}
