/*
 * Copyright 2016 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.idea.blaze.base.run.producers;

import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import java.util.Objects;
import javax.annotation.Nullable;

/** Runs tests in all packages below selected directory */
public class AllInPackageBlazeConfigurationProducer
    extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {

  public AllInPackageBlazeConfigurationProducer() {
    super(BlazeCommandRunConfigurationType.getInstance());
  }

  @Override
  protected boolean doSetupConfigFromContext(
      BlazeCommandRunConfiguration configuration,
      ConfigurationContext context,
      Ref<PsiElement> sourceElement) {

    PsiDirectory dir = getTestDirectory(context);
    if (dir == null) {
      return false;
    }
    WorkspaceRoot root = WorkspaceRoot.fromProject(context.getModule().getProject());
    WorkspacePath packagePath = getWorkspaceRelativeDirectoryPath(root, dir);
    if (packagePath == null) {
      return false;
    }
    sourceElement.set(dir);

    configuration.setTarget(TargetExpression.allFromPackageRecursive(packagePath));
    BlazeCommandGenericRunConfigurationHandler handler =
        configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
    if (handler == null) {
      return false;
    }
    handler.setCommand(BlazeCommandName.TEST);
    configuration.setGeneratedName();
    return true;
  }

  @Override
  protected boolean doIsConfigFromContext(
      BlazeCommandRunConfiguration configuration, ConfigurationContext context) {

    PsiDirectory dir = getTestDirectory(context);
    if (dir == null) {
      return false;
    }
    WorkspaceRoot root = WorkspaceRoot.fromProject(context.getModule().getProject());
    WorkspacePath packagePath = getWorkspaceRelativeDirectoryPath(root, dir);
    if (packagePath == null) {
      return false;
    }
    BlazeCommandGenericRunConfigurationHandler handler =
        configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
    if (handler == null) {
      return false;
    }
    return Objects.equals(handler.getCommand(), BlazeCommandName.TEST)
        && Objects.equals(
            configuration.getTarget(), TargetExpression.allFromPackageRecursive(packagePath));
  }

  @Nullable
  private static PsiDirectory getTestDirectory(ConfigurationContext context) {
    WorkspaceRoot root = WorkspaceRoot.fromProject(context.getModule().getProject());
    PsiElement location = context.getPsiLocation();
    if (location instanceof PsiDirectory) {
      PsiDirectory dir = (PsiDirectory) location;
      if (isInWorkspace(root, dir)) {
        return dir;
      }
    }
    return null;
  }

  @Nullable
  private static WorkspacePath getWorkspaceRelativeDirectoryPath(
      WorkspaceRoot root, PsiDirectory dir) {
    VirtualFile file = dir.getVirtualFile();
    if (isInWorkspace(root, dir)) {
      return root.workspacePathFor(file);
    }
    return null;
  }

  private static boolean isInWorkspace(WorkspaceRoot root, PsiDirectory dir) {
    return root.isInWorkspace(dir.getVirtualFile());
  }
}
