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

import com.google.common.base.Joiner;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.ui.BlazeValidationResult;
import com.google.idea.blaze.base.ui.UiUtil;
import com.google.idea.blaze.base.vcs.BlazeVcsHandler;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.TextFieldWithHistory;
import java.awt.Dimension;
import java.io.File;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;

/** Option to use an existing workspace */
public abstract class UseExistingWorkspaceOption implements BlazeSelectWorkspaceOption {

  private final JComponent component;
  private final TextFieldWithHistory directoryField;
  private final BuildSystem buildSystem;

  protected UseExistingWorkspaceOption(BlazeNewProjectBuilder builder, BuildSystem buildSystem) {
    this.buildSystem = buildSystem;

    this.directoryField = new TextFieldWithHistory();
    directoryField.setHistory(builder.getWorkspaceHistory(buildSystem));
    directoryField.setHistorySize(BlazeNewProjectBuilder.HISTORY_SIZE);
    directoryField.setText(builder.getLastImportedWorkspace(buildSystem));

    JButton button = new JButton("...");
    button.addActionListener(action -> chooseDirectory());
    int buttonSize = directoryField.getPreferredSize().height;
    button.setPreferredSize(new Dimension(buttonSize, buttonSize));

    JComponent box =
        UiUtil.createHorizontalBox(
            HORIZONTAL_LAYOUT_GAP,
            getIconComponent(),
            new JLabel("Workspace:"),
            directoryField,
            button);
    UiUtil.setPreferredWidth(box, PREFERRED_COMPONENT_WIDTH);
    this.component = box;
  }

  protected abstract boolean isWorkspaceRoot(File file);

  protected abstract BlazeValidationResult validateWorkspaceRoot(File workspaceRoot);

  private boolean isWorkspaceRoot(VirtualFile file) {
    return isWorkspaceRoot(new File(file.getPath()));
  }

  protected abstract String fileChooserDescription();

  protected abstract Icon getBuildSystemIcon();

  protected abstract String getWorkspaceName(File workspaceRoot);

  @Override
  public BuildSystem getBuildSystemForWorkspace() {
    return buildSystem;
  }

  @Override
  public JComponent getUiComponent() {
    return component;
  }

  @Override
  public void commit() throws BlazeProjectCommitException {}

  @Override
  public WorkspaceRoot getWorkspaceRoot() {
    return new WorkspaceRoot(new File(getDirectory()));
  }

  @Override
  public File getFileBrowserRoot() {
    return new File(getDirectory());
  }

  @Override
  public String getWorkspaceName() {
    File workspaceRoot = new File(getDirectory());
    return getWorkspaceName(workspaceRoot);
  }

  @Override
  public BlazeValidationResult validate() {
    if (getDirectory().isEmpty()) {
      return BlazeValidationResult.failure("Please select a workspace");
    }

    File workspaceRootFile = new File(getDirectory());
    if (!workspaceRootFile.exists()) {
      return BlazeValidationResult.failure("Workspace does not exist");
    }

    WorkspaceRoot workspaceRoot = new WorkspaceRoot(workspaceRootFile);
    boolean hasVcsHandler =
        Arrays.stream(BlazeVcsHandler.EP_NAME.getExtensions())
            .anyMatch(vcsHandler -> vcsHandler.handlesProject(buildSystem, workspaceRoot));
    if (!hasVcsHandler) {
      StringBuilder sb = new StringBuilder();
      sb.append("Workspace is not of a supported VCS type. ");
      sb.append("VCS types considered were: ");
      Joiner.on(", ")
          .appendTo(
              sb,
              Arrays.stream(BlazeVcsHandler.EP_NAME.getExtensions())
                  .map(BlazeVcsHandler::getVcsName)
                  .collect(Collectors.toList()));
      return BlazeValidationResult.failure(sb.toString());
    }

    return validateWorkspaceRoot(workspaceRootFile);
  }

  private String getDirectory() {
    return directoryField.getText().trim();
  }

  private void chooseDirectory() {
    FileChooserDescriptor descriptor =
        new FileChooserDescriptor(false, true, false, false, false, false) {
          @Override
          public boolean isFileSelectable(VirtualFile file) {
            // Default implementation doesn't filter directories,
            // we want to make sure only workspace roots are selectable
            return super.isFileSelectable(file) && isWorkspaceRoot(file);
          }

          @Override
          public Icon getIcon(VirtualFile file) {
            if (buildSystem == BuildSystem.Bazel) {
              // isWorkspaceRoot requires file system calls -- it's too expensive
              return super.getIcon(file);
            }
            if (isWorkspaceRoot(file)) {
              return AllIcons.Nodes.SourceFolder;
            }
            return super.getIcon(file);
          }
        }.withHideIgnored(false)
            .withTitle("Select Workspace Root")
            .withDescription(fileChooserDescription())
            .withFileFilter(this::isWorkspaceRoot);
    FileChooserDialog chooser =
        FileChooserFactory.getInstance().createFileChooser(descriptor, null, null);

    final VirtualFile[] files;
    File existingLocation = new File(getDirectory());
    if (existingLocation.exists()) {
      VirtualFile toSelect =
          LocalFileSystem.getInstance().refreshAndFindFileByPath(existingLocation.getPath());
      files = chooser.choose(null, toSelect);
    } else {
      files = chooser.choose(null);
    }
    if (files.length == 0) {
      return;
    }
    VirtualFile file = files[0];
    directoryField.setText(file.getPath());
  }

  private JComponent getIconComponent() {
    JLabel iconPanel =
        new JLabel(IconLoader.getIconSnapshot(getBuildSystemIcon())) {
          @Override
          public boolean isEnabled() {
            return true;
          }
        };
    UiUtil.setPreferredWidth(iconPanel, 16);
    return iconPanel;
  }
}
