/*
 * Copyright 2017 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.sync.workspace;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.TargetName;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.sync.SyncCache;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/** External-workspace-aware resolution of workspace paths. */
public class WorkspaceHelper {

  private static class Workspace {
    private final WorkspaceRoot root;
    @Nullable private final String externalWorkspaceName;

    private Workspace(WorkspaceRoot root, @Nullable String externalWorkspaceName) {
      this.root = root;
      this.externalWorkspaceName = externalWorkspaceName;
    }
  }

  @Nullable
  public static WorkspaceRoot resolveExternalWorkspace(Project project, String workspaceName) {
    Map<String, WorkspaceRoot> externalWorkspaces = getExternalWorkspaceRoots(project);
    return externalWorkspaces != null ? externalWorkspaces.get(workspaceName) : null;
  }

  /** Resolves the parent blaze package corresponding to this label. */
  @Nullable
  public static File resolveBlazePackage(Project project, Label label) {
    if (!label.isExternal()) {
      WorkspacePathResolver pathResolver =
          WorkspacePathResolverProvider.getInstance(project).getPathResolver();
      return pathResolver != null ? pathResolver.resolveToFile(label.blazePackage()) : null;
    }
    Map<String, WorkspaceRoot> externalWorkspaces = getExternalWorkspaceRoots(project);
    if (externalWorkspaces == null) {
      return null;
    }
    WorkspaceRoot root = externalWorkspaces.get(label.externalWorkspaceName());
    return root != null ? root.fileForPath(label.blazePackage()) : null;
  }

  @Nullable
  public static WorkspacePath resolveWorkspacePath(Project project, File absoluteFile) {
    Workspace workspace = resolveWorkspace(project, absoluteFile);
    return workspace != null ? workspace.root.workspacePathForSafe(absoluteFile) : null;
  }

  /** Converts a file to the corresponding BUILD label for this project, if valid. */
  @Nullable
  public static Label getBuildLabel(Project project, File absoluteFile) {
    Workspace workspace = resolveWorkspace(project, absoluteFile);
    if (workspace == null) {
      return null;
    }
    WorkspacePath workspacePath = workspace.root.workspacePathForSafe(absoluteFile);
    if (workspacePath == null) {
      return null;
    }
    return deriveLabel(project, workspace, workspacePath);
  }

  @Nullable
  private static Workspace resolveWorkspace(Project project, File absoluteFile) {
    WorkspacePathResolver pathResolver =
        WorkspacePathResolverProvider.getInstance(project).getPathResolver();
    if (pathResolver == null) {
      return null;
    }

    // try project workspace first
    WorkspaceRoot root = pathResolver.findWorkspaceRoot(absoluteFile);
    if (root != null) {
      return new Workspace(root, null);
    }

    Map<String, WorkspaceRoot> externalWorkspaces = getExternalWorkspaceRoots(project);
    if (externalWorkspaces == null) {
      return null;
    }
    for (Entry<String, WorkspaceRoot> entry : externalWorkspaces.entrySet()) {
      root = entry.getValue();
      WorkspacePath workspacePath = root.workspacePathForSafe(absoluteFile);
      if (workspacePath != null) {
        return new Workspace(root, entry.getKey());
      }
    }
    return null;
  }

  private static Label deriveLabel(
      Project project, Workspace workspace, WorkspacePath workspacePath) {
    BuildSystemProvider provider = Blaze.getBuildSystemProvider(project);
    File file = workspace.root.fileForPath(workspacePath);
    if (provider.isBuildFile(file.getName())) {
      return Label.create(
          workspace.externalWorkspaceName,
          workspace.root.workspacePathFor(file.getParentFile()),
          TargetName.create("__pkg__"));
    }
    WorkspacePath packagePath = getPackagePath(provider, workspace.root, workspacePath);
    if (packagePath == null) {
      return null;
    }
    TargetName targetName =
        TargetName.createIfValid(
            FileUtil.getRelativePath(workspace.root.fileForPath(packagePath), file));
    return targetName != null
        ? Label.create(workspace.externalWorkspaceName, packagePath, targetName)
        : null;
  }

  private static WorkspacePath getPackagePath(
      BuildSystemProvider provider, WorkspaceRoot root, WorkspacePath workspacePath) {
    File file = root.fileForPath(workspacePath).getParentFile();
    while (file != null && FileUtil.isAncestor(root.directory(), file, false)) {
      if (provider.findBuildFileInDirectory(file) != null) {
        return root.workspacePathFor(file);
      }
      file = file.getParentFile();
    }
    return null;
  }

  @Nullable
  private static synchronized Map<String, WorkspaceRoot> getExternalWorkspaceRoots(
      Project project) {
    if (Blaze.getBuildSystem(project) == BuildSystem.Blaze) {
      return ImmutableMap.of();
    }
    return SyncCache.getInstance(project)
        .get(WorkspaceHelper.class, WorkspaceHelper::enumerateExternalWorkspaces);
  }

  @SuppressWarnings("unused")
  private static Map<String, WorkspaceRoot> enumerateExternalWorkspaces(
      Project project, BlazeProjectData blazeProjectData) {
    FileAttributeProvider provider = FileAttributeProvider.getInstance();
    File[] children = provider.listFiles(getExternalSourceRoot(blazeProjectData));
    if (children == null) {
      return ImmutableMap.of();
    }
    return Arrays.stream(children)
        .filter(provider::isDirectory)
        .collect(Collectors.toMap(File::getName, WorkspaceRoot::new));
  }

  @VisibleForTesting
  public static File getExternalSourceRoot(BlazeProjectData projectData) {
    return new File(projectData.blazeInfo.getOutputBase(), "external");
  }
}
