// 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.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.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 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);
  }
}
