/*
 * Copyright 2020 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.devtools.build.android.desugar.testing.junit;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.desugar.langmodel.ClassName;
import com.google.devtools.build.android.desugar.langmodel.MemberUseKind;
import com.google.devtools.build.android.desugar.langmodel.MethodInvocationSite;
import com.google.devtools.build.android.desugar.langmodel.MethodKey;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;

/** Static utilities that facilities desugar testing. */
public class DesugarTestHelpers {

  /**
   * A helper method that reads file paths into an array from the JVM flag value associated with
   * {@param jvmFlagKey}.
   */
  public static Path[] getRuntimePathsFromJvmFlag(String jvmFlagKey) {
    String jvmPropertyValue =
        checkNotNull(
            System.getProperty(jvmFlagKey),
            "Expected JVM Option to be specified: -D<%s>=<YourValue>",
            jvmFlagKey);
    return Splitter.on(" ").trimResults().splitToList(jvmPropertyValue).stream()
        .map(Paths::get)
        .toArray(Path[]::new);
  }

  /** Find all matched method invocation instructions in the given method. */
  public static ImmutableList<MethodInvocationSite> findMethodInvocationSites(
      MethodNode enclosingMethod,
      String methodOwnerRegex,
      String methodNameRegex,
      String methodDescRegex) {
    Predicate<String> methodOwnerPredicate = Pattern.compile(methodOwnerRegex).asPredicate();
    Predicate<String> methodNamePredicate = Pattern.compile(methodNameRegex).asPredicate();
    Predicate<String> methodDescPredicate = Pattern.compile(methodDescRegex).asPredicate();
    AbstractInsnNode[] instructions = enclosingMethod.instructions.toArray();
    return Arrays.stream(instructions)
        .filter(node -> node.getType() == AbstractInsnNode.METHOD_INSN)
        .map(node -> (MethodInsnNode) node)
        .filter(node -> methodOwnerPredicate.test(node.owner))
        .filter(node -> methodNamePredicate.test(node.name))
        .filter(node -> methodDescPredicate.test(node.desc))
        .map(
            node ->
                MethodInvocationSite.builder()
                    .setInvocationKind(MemberUseKind.fromValue(node.getOpcode()))
                    .setMethod(MethodKey.create(ClassName.create(node.owner), node.name, node.desc))
                    .setIsInterface(node.itf)
                    .build())
        .collect(toImmutableList());
  }

  private DesugarTestHelpers() {}
}
