/*
 * 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.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
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.WorkspacePathResolverImpl;
import com.google.idea.blaze.base.ui.BlazeValidationResult;
import com.google.idea.blaze.base.ui.UiUtil;
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 icons.BlazeIcons;
import java.awt.Dimension;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;

/** Allows importing an existing bazel workspace */
public class UseExistingBazelWorkspaceOption implements BlazeSelectWorkspaceOption {

  private final JComponent component;
  private final TextFieldWithHistory directoryField;

  public UseExistingBazelWorkspaceOption(BlazeNewProjectBuilder builder) {
    this.directoryField = new TextFieldWithHistory();
    this.directoryField.setHistory(builder.getWorkspaceHistory(BuildSystem.Bazel));
    this.directoryField.setHistorySize(BlazeNewProjectBuilder.HISTORY_SIZE);
    this.directoryField.setText(builder.getLastImportedWorkspace(BuildSystem.Bazel));

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

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

  @Override
  public WorkspacePathResolver getWorkspacePathResolver() {
    return new WorkspacePathResolverImpl(getWorkspaceRoot());
  }

  @Override
  public String getOptionName() {
    return "use-existing-bazel-workspace";
  }

  @Override
  public String getOptionText() {
    return "Use existing bazel workspace";
  }

  private static boolean isWorkspaceRoot(File file) {
    return BuildSystemProvider.getWorkspaceRootProvider(BuildSystem.Bazel).isWorkspaceRoot(file);
  }

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

  @Override
  public BuildSystem getBuildSystemForWorkspace() {
    return BuildSystem.Bazel;
  }

  @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 workspaceRoot.getName();
  }

  @Override
  public String getBranchName() {
    return null;
  }

  @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");
    }
    if (!isWorkspaceRoot(workspaceRootFile)) {
      return BlazeValidationResult.failure(
          "Invalid workspace root: choose a bazel workspace directory "
              + "(containing a WORKSPACE file)");
    }
    return BlazeValidationResult.success();
  }

  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);
          }
        }.withHideIgnored(false)
            .withTitle("Select Workspace Root")
            .withDescription("Select the directory of the workspace you want to use.")
            .withFileFilter(UseExistingBazelWorkspaceOption::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 static JComponent getIconComponent() {
    JLabel iconPanel =
        new JLabel(IconLoader.getIconSnapshot(BlazeIcons.BazelLeaf)) {
          @Override
          public boolean isEnabled() {
            return true;
          }
        };
    UiUtil.setPreferredWidth(iconPanel, 16);
    return iconPanel;
  }
}
