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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.io.VirtualFileSystemProvider;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.BlazeVersionData;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.model.primitives.WorkspaceType;
import com.google.idea.blaze.base.projectview.ProjectView;
import com.google.idea.blaze.base.projectview.ProjectViewEdit;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.ProjectViewSet.ProjectViewFile;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.ScalarSection;
import com.google.idea.blaze.base.projectview.section.sections.AdditionalLanguagesSection;
import com.google.idea.blaze.base.projectview.section.sections.WorkspaceTypeSection;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.blaze.base.sync.BlazeSyncManager;
import com.google.idea.blaze.base.sync.BlazeSyncParams;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.GenericSourceFolderProvider;
import com.google.idea.blaze.base.sync.SourceFolderProvider;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.common.experiments.BoolExperiment;
import com.google.idea.sdkcompat.python.PythonFacetUtil;
import com.google.idea.sdkcompat.transactions.Transactions;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.NavigatableAdapter;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.PythonModuleTypeBase;
import com.jetbrains.python.facet.LibraryContributingFacet;
import com.jetbrains.python.sdk.PythonSdkType;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/** Allows people to use a python workspace. */
public class BlazePythonSyncPlugin extends BlazeSyncPlugin.Adapter {

  private static final Logger logger = Logger.getInstance(BlazePythonSyncPlugin.class);

  private static final BoolExperiment refreshExecRoot =
      new BoolExperiment("refresh.exec.root.python", true);

  @Override
  public Set<LanguageClass> getSupportedLanguagesInWorkspace(WorkspaceType workspaceType) {
    // supported for legacy reasons, but otherwise ignored.
    return ImmutableSet.of(LanguageClass.PYTHON);
  }

  @Override
  public Set<LanguageClass> getAlwaysActiveLanguages() {
    return ImmutableSet.of(LanguageClass.PYTHON);
  }

  @Nullable
  @Override
  public ModuleType getWorkspaceModuleType(WorkspaceType workspaceType) {
    // left here for backwards compatibility -- python workspace types are deprecated.
    if (workspaceType == WorkspaceType.PYTHON && supportsPythonWorkspaceType()) {
      return PythonModuleTypeBase.getInstance();
    }
    return null;
  }

  private static boolean supportsPythonWorkspaceType() {
    return !PlatformUtils.isCLion();
  }

  @Override
  public ImmutableList<WorkspaceType> getSupportedWorkspaceTypes() {
    // 'supports' python by giving a more detailed error message with quick-fix later in the sync
    // process, in the case where a python workspace type is not supported.
    return ImmutableList.of(WorkspaceType.PYTHON);
  }

  @Nullable
  @Override
  public SourceFolderProvider getSourceFolderProvider(BlazeProjectData projectData) {
    if (!projectData.workspaceLanguageSettings.isWorkspaceType(WorkspaceType.PYTHON)) {
      return null;
    }
    return GenericSourceFolderProvider.INSTANCE;
  }

  @Override
  public void updateProjectStructure(
      Project project,
      BlazeContext context,
      WorkspaceRoot workspaceRoot,
      ProjectViewSet projectViewSet,
      BlazeProjectData blazeProjectData,
      @Nullable BlazeProjectData oldBlazeProjectData,
      ModuleEditor moduleEditor,
      Module workspaceModule,
      ModifiableRootModel workspaceModifiableModel) {
    updatePythonFacet(context, blazeProjectData, workspaceModule, workspaceModifiableModel);
  }

  @Override
  public void refreshVirtualFileSystem(BlazeProjectData blazeProjectData) {
    if (!blazeProjectData.workspaceLanguageSettings.isLanguageActive(LanguageClass.PYTHON)) {
      return;
    }
    if (!refreshExecRoot.getValue()) {
      return;
    }
    long start = System.currentTimeMillis();
    refreshExecRoot(blazeProjectData);
    long end = System.currentTimeMillis();
    logger.info(String.format("Refreshing execution root took: %d ms", (end - start)));
  }

  private static void refreshExecRoot(BlazeProjectData blazeProjectData) {
    // recursive refresh of the blaze execution root. This is required because our blaze aspect
    // can't yet tell us exactly which genfiles are required to resolve the project.
    VirtualFile execRoot =
        VirtualFileSystemProvider.getInstance()
            .getSystem()
            .refreshAndFindFileByIoFile(blazeProjectData.blazeInfo.getExecutionRoot());
    if (execRoot != null) {
      VfsUtil.markDirtyAndRefresh(false, true, true, execRoot);
    }
  }

  private static void updatePythonFacet(
      BlazeContext context,
      BlazeProjectData blazeProjectData,
      Module workspaceModule,
      ModifiableRootModel workspaceModifiableModel) {
    if (!blazeProjectData.workspaceLanguageSettings.isLanguageActive(LanguageClass.PYTHON)
        || blazeProjectData.workspaceLanguageSettings.isWorkspaceType(WorkspaceType.PYTHON)) {
      removeFacet(workspaceModule);
      return;
    }
    if (ModuleType.get(workspaceModule) instanceof PythonModuleTypeBase) {
      return;
    }
    LibraryContributingFacet<?> pythonFacet = getOrCreatePythonFacet(context, workspaceModule);
    if (pythonFacet == null) {
      return;
    }
    Library pythonLib = getFacetLibrary(pythonFacet);
    if (pythonLib != null) {
      workspaceModifiableModel.addLibraryEntry(pythonLib);
    }
  }

  private static void removeFacet(Module workspaceModule) {
    FacetManager manager = FacetManager.getInstance(workspaceModule);
    ModifiableFacetModel facetModel = manager.createModifiableModel();
    LibraryContributingFacet<?> facet = manager.findFacet(PythonFacetUtil.getFacetId(), "Python");
    if (facet != null) {
      facetModel.removeFacet(facet);
      facetModel.commit();
    }
  }

  @Nullable
  private static LibraryContributingFacet<?> getOrCreatePythonFacet(
      BlazeContext context, Module module) {
    LibraryContributingFacet<?> facet = findPythonFacet(module);
    if (facet != null && facetHasSdk(facet)) {
      return facet;
    }
    FacetManager manager = FacetManager.getInstance(module);
    ModifiableFacetModel facetModel = manager.createModifiableModel();
    if (facet != null) {
      // we can't modify in place, IntelliJ has no hook to trigger change events. Instead we create
      // a new facet.
      facetModel.removeFacet(facet);
    }
    Sdk sdk = getOrCreatePythonSdk();
    if (sdk == null) {
      String msg =
          "Unable to find a Python SDK installed.\n"
              + "After configuring a suitable SDK in the \"Project Structure\" dialog, "
              + "sync the project again.";
      IssueOutput.error(msg).submit(context);
      return null;
    }
    facet = manager.createFacet(PythonFacetUtil.getTypeInstance(), "Python", null);
    facetModel.addFacet(facet);
    facetModel.commit();
    return facet;
  }

  private static boolean facetHasSdk(LibraryContributingFacet<?> facet) {
    // facets aren't properly updated when SDKs change (e.g. when they're deleted), so we need to
    // manually check against the full list.
    Sdk sdk = PythonFacetUtil.getSdk(facet);
    return sdk != null && PythonSdkType.getAllSdks().contains(sdk);
  }

  @Nullable
  private static Library getFacetLibrary(LibraryContributingFacet<?> facet) {
    Sdk sdk = PythonFacetUtil.getSdk(facet);
    if (sdk == null) {
      return null;
    }
    return LibraryTablesRegistrar.getInstance()
        .getLibraryTable()
        .getLibraryByName(
            sdk.getName() + LibraryContributingFacet.PYTHON_FACET_LIBRARY_NAME_SUFFIX);
  }

  private static LibraryContributingFacet<?> findPythonFacet(Module module) {
    final Facet<?>[] allFacets = FacetManager.getInstance(module).getAllFacets();
    for (Facet<?> facet : allFacets) {
      if ((facet instanceof LibraryContributingFacet)
          && (facet.getTypeId() == PythonFacetUtil.getFacetId())) {
        return (LibraryContributingFacet<?>) facet;
      }
    }
    return null;
  }

  @Override
  public void updateProjectSdk(
      Project project,
      BlazeContext context,
      ProjectViewSet projectViewSet,
      BlazeVersionData blazeVersionData,
      BlazeProjectData blazeProjectData) {
    if (!blazeProjectData.workspaceLanguageSettings.isWorkspaceType(WorkspaceType.PYTHON)) {
      return;
    }
    Sdk currentSdk = ProjectRootManager.getInstance(project).getProjectSdk();
    if (currentSdk != null && currentSdk.getSdkType() instanceof PythonSdkType) {
      return;
    }
    Sdk sdk = getOrCreatePythonSdk();
    if (sdk != null) {
      setProjectSdk(project, sdk);
    }
  }

  @Nullable
  private static Sdk getOrCreatePythonSdk() {
    List<Sdk> sdk = PythonSdkType.getAllSdks();
    if (!sdk.isEmpty()) {
      return sdk.get(0);
    }
    return SdkConfigurationUtil.createAndAddSDK("/usr/bin/python2.7", PythonSdkType.getInstance());
  }

  private static void setProjectSdk(Project project, Sdk sdk) {
    Transactions.submitWriteActionTransactionAndWait(
        () -> ProjectRootManager.getInstance(project).setProjectSdk(sdk));
  }

  @Override
  public boolean validateProjectView(
      @Nullable Project project,
      BlazeContext context,
      ProjectViewSet projectViewSet,
      WorkspaceLanguageSettings workspaceLanguageSettings) {
    ProjectViewFile topLevelProjectViewFile = projectViewSet.getTopLevelProjectViewFile();
    if (!supportsPythonWorkspaceType()
        && workspaceLanguageSettings.isWorkspaceType(WorkspaceType.PYTHON)) {
      String msg = "Python workspace type is not supported (and is unnecessary) for this IDE. ";
      boolean fixable =
          topLevelProjectViewFile != null
              && topLevelProjectViewFile.projectView.getScalarValue(WorkspaceTypeSection.KEY)
                  == WorkspaceType.PYTHON;
      msg +=
          fixable
              ? "Click here to remove it, retaining python support"
              : "Please remove it and resync.";
      IssueOutput.error(msg)
          .navigatable(
              project == null || !fixable
                  ? null
                  : new NavigatableAdapter() {
                    @Override
                    public void navigate(boolean requestFocus) {
                      fixLanguageSupport(project, true);
                    }
                  })
          .submit(context);
      return false;
    }
    return true;
  }

  private static void fixLanguageSupport(Project project, boolean removeWorkspaceType) {
    ProjectViewEdit edit =
        ProjectViewEdit.editLocalProjectView(
            project,
            builder -> {
              if (removeWorkspaceType) {
                removePythonWorkspaceType(builder);
              }
              removeFromAdditionalLanguages(builder);
              return true;
            });
    if (edit == null) {
      Messages.showErrorDialog(
          "Could not modify project view. Check for errors in your project view and try again",
          "Error");
      return;
    }
    edit.apply();

    BlazeSyncManager.getInstance(project)
        .requestProjectSync(
            new BlazeSyncParams.Builder("Sync", BlazeSyncParams.SyncMode.INCREMENTAL)
                .addProjectViewTargets(true)
                .addWorkingSet(BlazeUserSettings.getInstance().getExpandSyncToWorkingSet())
                .build());
  }

  private static void removePythonWorkspaceType(ProjectView.Builder builder) {
    ScalarSection<WorkspaceType> section = builder.getLast(WorkspaceTypeSection.KEY);
    if (section != null && section.getValue() == WorkspaceType.PYTHON) {
      builder.remove(section);
    }
  }

  private static void removeFromAdditionalLanguages(ProjectView.Builder builder) {
    ListSection<LanguageClass> existingSection = builder.getLast(AdditionalLanguagesSection.KEY);
    builder.replace(
        existingSection,
        ListSection.update(AdditionalLanguagesSection.KEY, existingSection)
            .remove(LanguageClass.PYTHON));
  }
}
