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

import com.google.idea.blaze.base.lang.projectview.language.ProjectViewFileType;
import com.google.idea.blaze.base.lang.projectview.language.ProjectViewLanguage;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import com.google.idea.blaze.base.scope.OutputSink;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverProvider;
import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.file.impl.FileManager;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.components.JBLabel;
import java.awt.Dimension;
import java.awt.KeyboardFocusManager;
import java.util.List;
import javax.annotation.Nullable;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.UIManager;
import org.jetbrains.annotations.NotNull;
import org.picocontainer.MutablePicoContainer;

/** UI for changing the ProjectView. */
public class ProjectViewUi {

  private static final String USE_SHARED_PROJECT_VIEW = "Use shared project view file";

  private final Disposable parentDisposable;
  private EditorEx projectViewEditor;
  private JCheckBox useShared;

  private WorkspacePathResolver workspacePathResolver;
  private boolean useSharedProjectView;
  private boolean allowEditShared;
  private String sharedProjectViewText;
  private boolean settingsInitialized;

  public ProjectViewUi(Disposable parentDisposable) {
    this.parentDisposable = parentDisposable;
  }

  /**
   * To support the custom language features, we need a ProjectImpl, and it's not desirable to
   * create one from scratch.<br>
   *
   * @return the current, non-default project, if one exists, else the default project.
   */
  public static Project getProject() {
    Project project = (Project) DataManager.getInstance().getDataContext().getData("project");
    if (project != null && project instanceof ProjectImpl) {
      return project;
    }
    return ProjectManager.getInstance().getDefaultProject();
  }

  public static Dimension getMinimumSize() {
    return new Dimension(1000, 550);
  }

  private static EditorEx createEditor(String tooltip) {
    Project project = getProject();
    LightVirtualFile virtualFile =
        new LightVirtualFile("mockProjectViewFile", ProjectViewLanguage.INSTANCE, "");
    final Document document =
        ((EditorFactoryImpl) EditorFactory.getInstance()).createDocument(true);
    ((DocumentImpl) document).setAcceptSlashR(true);
    FileDocumentManagerImpl.registerDocument(document, virtualFile);

    FileManager fileManager = ((PsiManagerEx) PsiManager.getInstance(project)).getFileManager();
    fileManager.setViewProvider(virtualFile, fileManager.createFileViewProvider(virtualFile, true));

    if (project.isDefault()) {
      // Undo-redo doesn't work with the default project.
      // Explicitly turn it off to avoid error dialogs.
      UndoUtil.disableUndoFor(document);
    }

    EditorEx editor =
        (EditorEx)
            EditorFactory.getInstance()
                .createEditor(document, project, ProjectViewFileType.INSTANCE, false);
    final EditorSettings settings = editor.getSettings();
    settings.setLineNumbersShown(false);
    settings.setLineMarkerAreaShown(false);
    settings.setFoldingOutlineShown(false);
    settings.setRightMarginShown(false);
    settings.setAdditionalPageAtBottom(false);
    editor.getComponent().setMinimumSize(getMinimumSize());
    editor.getComponent().setPreferredSize(getMinimumSize());
    editor.getComponent().setToolTipText(tooltip);
    editor.getComponent().setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
    editor.getComponent().setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
    return editor;
  }

  public void fillUi(JPanel canvas) {
    String tooltip =
        "Enter a project view descriptor file."
            + (Blaze.defaultBuildSystem() == BuildSystem.Blaze
                ? " See 'go/intellij/docs/project-views.md' for more information."
                : "");

    projectViewEditor = createEditor(tooltip);
    projectViewEditor
        .getColorsScheme()
        .setColor(EditorColors.READONLY_BACKGROUND_COLOR, UIManager.getColor("Label.background"));
    Disposer.register(
        parentDisposable, () -> EditorFactory.getInstance().releaseEditor(projectViewEditor));

    JBLabel labelsLabel = new JBLabel("Project View");
    labelsLabel.setToolTipText(tooltip);
    canvas.add(labelsLabel, UiUtil.getFillLineConstraints(0));

    canvas.add(projectViewEditor.getComponent(), UiUtil.getFillLineConstraints(0));

    useShared = new JCheckBox(USE_SHARED_PROJECT_VIEW);
    useShared.addActionListener(
        e -> {
          useSharedProjectView = useShared.isSelected();
          if (useSharedProjectView) {
            setProjectViewText(sharedProjectViewText);
          }
          updateTextAreasEnabled();
        });
    canvas.add(useShared, UiUtil.getFillLineConstraints(0));
  }

  public void init(
      WorkspacePathResolver workspacePathResolver,
      String projectViewText,
      @Nullable String sharedProjectViewText,
      @Nullable WorkspacePath sharedProjectViewWorkspacePath,
      boolean useSharedProjectView,
      boolean allowEditShared) {
    this.workspacePathResolver = workspacePathResolver;
    this.useSharedProjectView = useSharedProjectView;
    this.allowEditShared = allowEditShared;
    this.sharedProjectViewText = sharedProjectViewText;

    assert !(useSharedProjectView && sharedProjectViewText == null);

    if (sharedProjectViewWorkspacePath != null) {
      useShared.setText(
          USE_SHARED_PROJECT_VIEW + ": " + sharedProjectViewWorkspacePath.relativePath());
    }

    useShared.setSelected(useSharedProjectView);
    useShared.setEnabled(sharedProjectViewText != null);

    setDummyWorkspacePathResolverProvider(this.workspacePathResolver);
    setProjectViewText(projectViewText);
    settingsInitialized = true;
  }

  private void setDummyWorkspacePathResolverProvider(WorkspacePathResolver workspacePathResolver) {
    MutablePicoContainer container = (MutablePicoContainer) getProject().getPicoContainer();
    Class<WorkspacePathResolverProvider> key = WorkspacePathResolverProvider.class;
    Object oldProvider = container.getComponentInstance(key);
    container.unregisterComponent(key.getName());
    container.registerComponentInstance(
        key.getName(), (WorkspacePathResolverProvider) () -> workspacePathResolver);
    if (!settingsInitialized) {
      Disposer.register(
          parentDisposable,
          () -> {
            container.unregisterComponent(key.getName());
            if (oldProvider != null) {
              container.registerComponentInstance(key.getName(), oldProvider);
            }
          });
    }
  }

  private void setProjectViewText(String projectViewText) {
    new WriteAction() {
      @Override
      protected void run(@NotNull Result result) throws Throwable {
        projectViewEditor.getDocument().setReadOnly(false);
        projectViewEditor.getDocument().setText(projectViewText);
      }
    }.execute();
    updateTextAreasEnabled();
  }

  private void updateTextAreasEnabled() {
    boolean editEnabled = allowEditShared || !useSharedProjectView;
    projectViewEditor.setViewer(!editEnabled);
    projectViewEditor.getDocument().setReadOnly(!editEnabled);
    projectViewEditor.reinitSettings();
  }

  public ProjectViewSet parseProjectView(final List<IssueOutput> issues) {
    final String projectViewText = projectViewEditor.getDocument().getText();
    final OutputSink<IssueOutput> issueCollector =
        output -> {
          issues.add(output);
          return OutputSink.Propagation.Continue;
        };
    return Scope.root(
        context -> {
          context.addOutputSink(IssueOutput.class, issueCollector);
          ProjectViewParser projectViewParser =
              new ProjectViewParser(context, workspacePathResolver);
          projectViewParser.parseProjectView(projectViewText);
          return projectViewParser.getResult();
        });
  }

  public boolean getUseSharedProjectView() {
    return this.useSharedProjectView;
  }
}
