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

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.structural.StructuralAccept;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;

public class DebugLocalInfo implements StructuralItem<DebugLocalInfo> {

  public enum PrintLevel {
    NONE,
    NAME,
    FULL
  }

  public static final PrintLevel PRINT_LEVEL = PrintLevel.NAME;

  public final DexString name;
  public final DexType type;
  public final DexString signature;

  private static void specify(StructuralSpecification<DebugLocalInfo, ?> spec) {
    spec.withItem(info -> info.name)
        .withItem(info -> info.type)
        .withNullableItem(info -> info.signature);
  }

  public DebugLocalInfo(DexString name, DexType type, DexString signature) {
    this.name = name;
    this.type = type;
    this.signature = signature;
  }

  @Override
  public DebugLocalInfo self() {
    return this;
  }

  @Override
  public StructuralAccept<DebugLocalInfo> getStructuralAccept() {
    return DebugLocalInfo::specify;
  }

  public static boolean localsInfoMapsEqual(
      Int2ReferenceMap<DebugLocalInfo> set0, Int2ReferenceMap<DebugLocalInfo> set1) {
    if (set0 == null) {
      return set1 == null;
    }
    if (set1 == null) {
      return false;
    }
    if (set0.keySet().size() != set1.keySet().size()) {
      return false;
    }
    for (int i : set0.keySet()) {
      if (!set0.get(i).equals(set1.get(i))) {
        return false;
      }
    }
    return true;
  }

  public static Int2ReferenceSortedMap<DebugLocalInfo> endingLocals(
      Int2ReferenceMap<DebugLocalInfo> previousLocals,
      Int2ReferenceMap<DebugLocalInfo> nextLocals) {
    Int2ReferenceSortedMap<DebugLocalInfo> ending = new Int2ReferenceAVLTreeMap<>();
    for (Entry<DebugLocalInfo> entry : previousLocals.int2ReferenceEntrySet()) {
      int register = entry.getIntKey();
      DebugLocalInfo local = entry.getValue();
      if (nextLocals.get(register) != local) {
        ending.put(register, local);
      }
    }
    return ending;
  }

  public static Int2ReferenceSortedMap<DebugLocalInfo> startingLocals(
      Int2ReferenceMap<DebugLocalInfo> previousLocals,
      Int2ReferenceMap<DebugLocalInfo> nextLocals) {
    Int2ReferenceSortedMap<DebugLocalInfo> starting = new Int2ReferenceAVLTreeMap<>();
    for (Entry<DebugLocalInfo> entry : nextLocals.int2ReferenceEntrySet()) {
      int register = entry.getIntKey();
      DebugLocalInfo local = entry.getValue();
      if (previousLocals.get(register) != local) {
        starting.put(register, local);
      }
    }
    return starting;
  }

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

  @Override
  public int hashCode() {
    int hash = 7 * name.hashCode() + 13 * type.hashCode();
    if (signature != null) {
      hash += 31 * signature.hashCode();
    }
    return hash;
  }

  @Override
  public String toString() {
    return toString(PRINT_LEVEL);
  }

  public String toString(PrintLevel printLevel) {
    switch (printLevel) {
      case NONE:
        return "";
      case NAME:
        return name.toString();
      case FULL:
        return name + ":" + (signature == null
            ? type
            : DescriptorUtils.descriptorToJavaType(signature.toString()));
      default:
        throw new Unreachable();
    }
  }
}
