// Copyright (c) 2020, 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.graph.LookupResult.LookupResultSuccess.LookupResultCollectionState;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

public abstract class LookupResult {

  public boolean isLookupResultFailure() {
    return false;
  }

  public boolean isLookupResultSuccess() {
    return false;
  }

  public LookupResultFailure asLookupResultFailure() {
    return null;
  }

  public LookupResultSuccess asLookupResultSuccess() {
    return null;
  }

  public final void forEach(Consumer<? super LookupTarget> onTarget) {
    forEach(onTarget, onTarget);
  }

  public abstract void forEach(
      Consumer<? super LookupMethodTarget> onMethodTarget,
      Consumer<? super LookupLambdaTarget> onLambdaTarget);

  public abstract void forEachFailureDependency(
      Consumer<? super DexEncodedMethod> methodCausingFailureConsumer);

  public static LookupResultSuccess createResult(
      Map<DexMethod, LookupMethodTarget> methodTargets,
      List<LookupLambdaTarget> lambdaTargets,
      List<DexEncodedMethod> methodsCausingFailure,
      LookupResultCollectionState state) {
    return new LookupResultSuccess(methodTargets, lambdaTargets, methodsCausingFailure, state);
  }

  public static LookupResultFailure createFailedResult() {
    return LookupResultFailure.INSTANCE;
  }

  public static LookupResultSuccess getIncompleteEmptyResult() {
    return LookupResultSuccess.EMPTY_INSTANCE;
  }

  public static class LookupResultSuccess extends LookupResult {

    private static final LookupResultSuccess EMPTY_INSTANCE =
        new LookupResultSuccess(
            new IdentityHashMap<>(),
            Collections.emptyList(),
            Collections.emptyList(),
            LookupResultCollectionState.Incomplete);

    private final Map<DexMethod, LookupMethodTarget> methodTargets;
    private final List<LookupLambdaTarget> lambdaTargets;
    private final List<DexEncodedMethod> methodsCausingFailure;
    private LookupResultCollectionState state;

    private LookupResultSuccess(
        Map<DexMethod, LookupMethodTarget> methodTargets,
        List<LookupLambdaTarget> lambdaTargets,
        List<DexEncodedMethod> methodsCausingFailure,
        LookupResultCollectionState state) {
      this.methodTargets = methodTargets;
      this.lambdaTargets = lambdaTargets;
      this.methodsCausingFailure = methodsCausingFailure;
      this.state = state;
    }

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

    public boolean isEmpty() {
      return methodTargets.isEmpty() && lambdaTargets.isEmpty();
    }

    public boolean hasMethodTargets() {
      return !methodTargets.isEmpty();
    }

    public boolean hasLambdaTargets() {
      return !lambdaTargets.isEmpty();
    }

    @Override
    public void forEach(
        Consumer<? super LookupMethodTarget> onMethodTarget,
        Consumer<? super LookupLambdaTarget> onLambdaTarget) {
      methodTargets.forEach((key, value) -> onMethodTarget.accept(value));
      lambdaTargets.forEach(onLambdaTarget);
    }

    @Override
    public void forEachFailureDependency(
        Consumer<? super DexEncodedMethod> methodCausingFailureConsumer) {
      methodsCausingFailure.forEach(methodCausingFailureConsumer);
    }

    public boolean contains(DexEncodedMethod method) {
      // Containment of a method in the lookup results only pertains to the method targets.
      return methodTargets.containsKey(method.getReference());
    }

    @Override
    public LookupResultSuccess asLookupResultSuccess() {
      return this;
    }

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

    public boolean isIncomplete() {
      return state == LookupResultCollectionState.Incomplete;
    }

    public boolean isComplete() {
      return state == LookupResultCollectionState.Complete;
    }

    public void setIncomplete() {
      // TODO(b/148769279): Remove when we have instantiated info.
      state = LookupResultCollectionState.Incomplete;
    }

    public LookupTarget getSingleLookupTarget() {
      if (isIncomplete() || methodTargets.size() + lambdaTargets.size() > 1) {
        return null;
      }
      // TODO(b/150932978): Check lambda targets implementation methods.
      if (methodTargets.size() == 1) {
        return methodTargets.values().iterator().next();
      } else if (lambdaTargets.size() == 1) {
        return lambdaTargets.get(0);
      }
      return null;
    }

    public enum LookupResultCollectionState {
      Complete,
      Incomplete,
    }

    public static class Builder {

      private final Map<DexMethod, LookupMethodTarget> methodTargets = new IdentityHashMap<>();
      private final List<LookupLambdaTarget> lambdaTargets = new ArrayList<>();
      private final List<DexEncodedMethod> methodsCausingFailure = new ArrayList<>();
      private final Set<DexType> typesCausingFailure = Sets.newIdentityHashSet();
      private LookupResultCollectionState state;

      public Builder addMethodTarget(LookupMethodTarget methodTarget) {
        assert methodTarget.isMethodTarget();
        methodTargets.putIfAbsent(methodTarget.asMethodTarget().getReference(), methodTarget);
        return this;
      }

      public Builder addLambdaTarget(LookupLambdaTarget lambdaTarget) {
        lambdaTargets.add(lambdaTarget);
        return this;
      }

      public Builder addMethodCausingFailure(DexEncodedMethod methodCausingFailure) {
        methodsCausingFailure.add(methodCausingFailure);
        return this;
      }

      public Builder addTypeCausingFailure(DexType typeCausingFailure) {
        typesCausingFailure.add(typeCausingFailure);
        return this;
      }

      public Builder setState(LookupResultCollectionState state) {
        this.state = state;
        return this;
      }

      public LookupResultSuccess build() {
        return new LookupResultSuccess(methodTargets, lambdaTargets, methodsCausingFailure, state);
      }
    }
  }

  public static class LookupResultFailure extends LookupResult {

    private static final LookupResultFailure INSTANCE = new LookupResultFailure();

    private LookupResultFailure() {
      // Empty to only allow creation locally.
    }

    @Override
    public LookupResultFailure asLookupResultFailure() {
      return this;
    }

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

    @Override
    public void forEach(
        Consumer<? super LookupMethodTarget> onMethodTarget,
        Consumer<? super LookupLambdaTarget> onLambdaTarget) {
      // Nothing to iterate for a failed lookup.
    }

    @Override
    public void forEachFailureDependency(
        Consumer<? super DexEncodedMethod> methodCausingFailureConsumer) {
      // TODO: record and emit failure dependencies.
    }
  }
}
