// 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 java.util.IdentityHashMap;
import java.util.Map;

/**
 * A GraphLense implements a virtual view on top of the graph, used to delay global rewrites until
 * later IR processing stages.
 * <p>
 * Valid remappings are limited to the following operations:
 * <ul>
 * <li>Mapping a classes type to one of the super/subtypes.</li>
 * <li>Renaming private methods/fields.</li>
 * <li>Moving methods/fields to a super/subclass.</li>
 * <li>Replacing method/field references by the same method/field on a super/subtype</li>
 * </ul>
 * Note that the latter two have to take visibility into account.
 */
public abstract class GraphLense {

  public static class Builder {

    private Builder() {

    }

    private final Map<DexType, DexType> typeMap = new IdentityHashMap<>();
    private final Map<DexMethod, DexMethod> methodMap = new IdentityHashMap<>();
    private final Map<DexField, DexField> fieldMap = new IdentityHashMap<>();

    public void map(DexType from, DexType to) {
      typeMap.put(from, to);
    }

    public void map(DexMethod from, DexMethod to) {
      methodMap.put(from, to);
    }

    public void map(DexField from, DexField to) {
      fieldMap.put(from, to);
    }

    public GraphLense build(DexItemFactory dexItemFactory) {
      return build(new IdentityGraphLense(), dexItemFactory);
    }

    public GraphLense build(GraphLense previousLense, DexItemFactory dexItemFactory) {
      return new NestedGraphLense(typeMap, methodMap, fieldMap, previousLense, dexItemFactory);
    }

  }

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

  public abstract DexType lookupType(DexType type, DexEncodedMethod context);

  public abstract DexMethod lookupMethod(DexMethod method, DexEncodedMethod context);

  public abstract DexField lookupField(DexField field, DexEncodedMethod context);

  public abstract boolean isContextFree();

  public static GraphLense getIdentityLense() {
    return new IdentityGraphLense();
  }

  public final boolean isIdentityLense() {
    return this instanceof IdentityGraphLense;
  }

  private static class IdentityGraphLense extends GraphLense {

    @Override
    public DexType lookupType(DexType type, DexEncodedMethod context) {
      return type;
    }

    @Override
    public DexMethod lookupMethod(DexMethod method, DexEncodedMethod context) {
      return method;
    }

    @Override
    public DexField lookupField(DexField field, DexEncodedMethod context) {
      return field;
    }

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

  private static class NestedGraphLense extends GraphLense {

    private final GraphLense previousLense;
    private final DexItemFactory dexItemFactory;

    private final Map<DexType, DexType> typeMap;
    private final Map<DexType, DexType> arrayTypeCache = new IdentityHashMap<>();
    private final Map<DexMethod, DexMethod> methodMap;
    private final Map<DexField, DexField> fieldMap;

    private NestedGraphLense(Map<DexType, DexType> typeMap, Map<DexMethod, DexMethod> methodMap,
        Map<DexField, DexField> fieldMap, GraphLense previousLense, DexItemFactory dexItemFactory) {
      this.typeMap = typeMap;
      this.methodMap = methodMap;
      this.fieldMap = fieldMap;
      this.previousLense = previousLense;
      this.dexItemFactory = dexItemFactory;
    }

    @Override
    public DexType lookupType(DexType type, DexEncodedMethod context) {
      if (type.isArrayType()) {
        DexType result = arrayTypeCache.get(type);
        if (result == null) {
          DexType baseType = type.toBaseType(dexItemFactory);
          DexType newType = lookupType(baseType, context);
          if (baseType == newType) {
            result = type;
          } else {
            result = type.replaceBaseType(newType, dexItemFactory);
          }
          arrayTypeCache.put(type, result);
        }
        return result;
      }
      DexType previous = previousLense.lookupType(type, context);
      return typeMap.getOrDefault(previous, previous);
    }

    @Override
    public DexMethod lookupMethod(DexMethod method, DexEncodedMethod context) {
      DexMethod previous = previousLense.lookupMethod(method, context);
      return methodMap.getOrDefault(previous, previous);
    }

    @Override
    public DexField lookupField(DexField field, DexEncodedMethod context) {
      DexField previous = previousLense.lookupField(field, context);
      return fieldMap.getOrDefault(previous, previous);
    }

    @Override
    public boolean isContextFree() {
      return previousLense.isContextFree();
    }
  }
}
