// 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.android.tools.r8.utils.collections.DexClassAndMethodSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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 DexClassAndMethod> onMethodTarget,
      Consumer<? super LookupLambdaTarget> onLambdaTarget);

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

  public static LookupResultSuccess createResult(
      DexClassAndMethodSet 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(
            DexClassAndMethodSet.empty(),
            Collections.emptyList(),
            Collections.emptyList(),
            LookupResultCollectionState.Incomplete);

    private final DexClassAndMethodSet methodTargets;
    private final List<LookupLambdaTarget> lambdaTargets;
    private final List<DexEncodedMethod> methodsCausingFailure;
    private LookupResultCollectionState state;

    private LookupResultSuccess(
        DexClassAndMethodSet 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 DexClassAndMethod> onMethodTarget,
        Consumer<? super LookupLambdaTarget> onLambdaTarget) {
      methodTargets.forEach(onMethodTarget);
      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.contains(method);
    }

    @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.iterator().next();
      } else if (lambdaTargets.size() == 1) {
        return lambdaTargets.get(0);
      }
      return null;
    }

    public enum LookupResultCollectionState {
      Complete,
      Incomplete,
    }

    public static class Builder {

      private final DexClassAndMethodSet methodTargets = DexClassAndMethodSet.create();
      private final List<LookupLambdaTarget> lambdaTargets = new ArrayList<>();
      private final List<DexEncodedMethod> methodsCausingFailure = new ArrayList<>();
      private LookupResultCollectionState state;

      public Builder addMethodTarget(DexClassAndMethod methodTarget) {
        methodTargets.add(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 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 DexClassAndMethod> 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.
    }
  }
}
