/*
 * 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.testmap;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetKey;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.TestTargetFinder;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
import com.google.idea.blaze.base.sync.SyncListener;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.project.Project;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * Used to locate tests from source files for things like right-clicks.
 *
 * <p>It's essentially a map from source file -> reachable test rules.
 */
public class TestTargetFilterImpl implements TestTargetFinder {

  private final Project project;
  @Nullable private TestMap testMap;

  static class TestMap {
    private final Project project;
    private final Multimap<File, TargetKey> rootsMap;
    private final TargetMap targetMap;

    TestMap(Project project, ArtifactLocationDecoder artifactLocationDecoder, TargetMap targetMap) {
      this.project = project;
      this.rootsMap = createRootsMap(artifactLocationDecoder, targetMap.targets());
      this.targetMap = targetMap;
    }

    private Collection<TargetIdeInfo> testTargetsForSourceFile(File sourceFile) {
      BlazeProjectData blazeProjectData =
          BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
      if (blazeProjectData != null) {
        return testTargetsForSourceFileImpl(blazeProjectData.reverseDependencies, sourceFile);
      }
      return ImmutableList.of();
    }

    @VisibleForTesting
    Collection<Label> testTargetsForSourceFile(
        ImmutableMultimap<TargetKey, TargetKey> rdepsMap, File sourceFile) {
      return testTargetsForSourceFileImpl(rdepsMap, sourceFile)
          .stream()
          .filter(TargetIdeInfo::isPlainTarget)
          .map(target -> target.key.label)
          .collect(Collectors.toList());
    }

    Collection<TargetIdeInfo> testTargetsForSourceFileImpl(
        ImmutableMultimap<TargetKey, TargetKey> rdepsMap, File sourceFile) {
      List<TargetIdeInfo> result = Lists.newArrayList();
      Collection<TargetKey> roots = rootsMap.get(sourceFile);

      Queue<TargetKey> todo = Queues.newArrayDeque();
      for (TargetKey label : roots) {
        todo.add(label);
      }
      Set<TargetKey> seen = Sets.newHashSet();
      while (!todo.isEmpty()) {
        TargetKey targetKey = todo.remove();
        if (!seen.add(targetKey)) {
          continue;
        }

        TargetIdeInfo target = targetMap.get(targetKey);
        if (isTestTarget(target)) {
          result.add(target);
        }
        for (TargetKey rdep : rdepsMap.get(targetKey)) {
          todo.add(rdep);
        }
      }
      return result;
    }

    static Multimap<File, TargetKey> createRootsMap(
        ArtifactLocationDecoder artifactLocationDecoder, Collection<TargetIdeInfo> targets) {
      Multimap<File, TargetKey> result = ArrayListMultimap.create();
      for (TargetIdeInfo target : targets) {
        for (ArtifactLocation source : target.sources) {
          result.put(artifactLocationDecoder.decode(source), target.key);
        }
      }
      return result;
    }

    private static boolean isTestTarget(@Nullable TargetIdeInfo target) {
      return target != null
          && target.kind != null
          && target.kind.isOneOf(
              Kind.ANDROID_ROBOLECTRIC_TEST,
              Kind.ANDROID_TEST,
              Kind.JAVA_TEST,
              Kind.GWT_TEST,
              Kind.CC_TEST,
              Kind.PY_TEST,
              Kind.GO_TEST);
    }
  }

  public TestTargetFilterImpl(Project project) {
    this.project = project;
  }

  @Override
  public Collection<TargetIdeInfo> testTargetsForSourceFile(File sourceFile) {
    TestMap testMap = getTestMap();
    if (testMap == null) {
      return ImmutableList.of();
    }
    return testMap.testTargetsForSourceFile(sourceFile);
  }

  private synchronized TestMap getTestMap() {
    if (testMap == null) {
      testMap = initTestMap();
    }
    return testMap;
  }

  @Nullable
  private TestMap initTestMap() {
    BlazeProjectData blazeProjectData =
        BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
    if (blazeProjectData == null) {
      return null;
    }
    return new TestMap(
        project, blazeProjectData.artifactLocationDecoder, blazeProjectData.targetMap);
  }

  private synchronized void clearMapData() {
    this.testMap = null;
  }

  static class ClearTestMap extends SyncListener.Adapter {
    @Override
    public void onSyncComplete(
        Project project,
        BlazeContext context,
        BlazeImportSettings importSettings,
        ProjectViewSet projectViewSet,
        BlazeProjectData blazeProjectData,
        SyncMode syncMode,
        SyncResult syncResult) {
      TestTargetFinder testTargetFinder = TestTargetFinder.getInstance(project);
      ((TestTargetFilterImpl) testTargetFinder).clearMapData();
    }
  }
}
