/*
 * 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 static com.google.common.base.Preconditions.checkState;

import com.google.common.base.Strings;
import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.projectview.ProjectView;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.sections.DirectoryEntry;
import com.google.idea.blaze.base.projectview.section.sections.DirectorySection;
import com.google.idea.blaze.base.projectview.section.sections.TargetSection;
import com.google.idea.blaze.base.projectview.section.sections.TextBlock;
import com.google.idea.blaze.base.projectview.section.sections.TextBlockSection;
import com.google.idea.blaze.base.sync.projectview.RelatedWorkspacePathFinder;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
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.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.TextFieldWithStoredHistory;
import java.awt.Dimension;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;

/** Generates a project view given a BUILD file */
public class GenerateFromBuildFileSelectProjectViewOption implements BlazeSelectProjectViewOption {
  private static final String LAST_WORKSPACE_PATH = "generate-from-build-file.last-workspace-path";
  private final BlazeNewProjectBuilder builder;
  private final BlazeWizardUserSettings userSettings;
  private final TextFieldWithStoredHistory buildFilePathField;
  private final JComponent component;

  public GenerateFromBuildFileSelectProjectViewOption(BlazeNewProjectBuilder builder) {
    this.builder = builder;
    this.userSettings = builder.getUserSettings();

    this.buildFilePathField = new TextFieldWithStoredHistory(LAST_WORKSPACE_PATH);
    buildFilePathField.setHistorySize(BlazeNewProjectBuilder.HISTORY_SIZE);
    buildFilePathField.setText(userSettings.get(LAST_WORKSPACE_PATH, ""));

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

    JComponent box =
        UiUtil.createHorizontalBox(
            HORIZONTAL_LAYOUT_GAP, new JLabel("BUILD file:"), buildFilePathField, button);
    UiUtil.setPreferredWidth(box, PREFERRED_COMPONENT_WIDTH);
    this.component = box;
  }

  @Override
  public String getOptionName() {
    return "generate-from-build-file";
  }

  @Override
  public String getOptionText() {
    return "Generate from BUILD file";
  }

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

  @Override
  public BlazeValidationResult validate() {
    String buildFilePath = getBuildFilePath();
    if (buildFilePath.isEmpty()) {
      return BlazeValidationResult.failure("BUILD file field cannot be empty.");
    }
    if (!WorkspacePath.validate(buildFilePath)) {
      return BlazeValidationResult.failure(
          "Invalid BUILD file path: specify a path relative to the workspace root.");
    }
    WorkspacePathResolver workspacePathResolver =
        builder.getWorkspaceOption().getWorkspacePathResolver();
    File file = workspacePathResolver.resolveToFile(new WorkspacePath(buildFilePath));
    if (!file.exists()) {
      return BlazeValidationResult.failure("BUILD file does not exist.");
    }
    BuildSystemProvider buildSystemProvider =
        BuildSystemProvider.getBuildSystemProvider(builder.getBuildSystem());
    checkState(buildSystemProvider != null);
    if (!buildSystemProvider.isBuildFile(file.getName())) {
      return BlazeValidationResult.failure("File must be a BUILD file.");
    }

    return BlazeValidationResult.success();
  }

  @Nullable
  @Override
  public String getInitialProjectViewText() {
    WorkspacePathResolver workspacePathResolver =
        builder.getWorkspaceOption().getWorkspacePathResolver();
    WorkspacePath workspacePath =
        new WorkspacePath(Strings.nullToEmpty(new File(getBuildFilePath()).getParent()));
    return guessProjectViewFromLocation(workspacePathResolver, workspacePath);
  }

  @Override
  public boolean allowAddDefaultProjectViewValues() {
    return true;
  }

  @Override
  public String getImportDirectory() {
    File buildFileParent = new File(getBuildFilePath()).getParentFile();
    return buildFileParent != null ? buildFileParent.getName() : null;
  }

  @Override
  public void commit() {
    userSettings.put(LAST_WORKSPACE_PATH, getBuildFilePath());
    buildFilePathField.addCurrentTextToHistory();
  }

  private static String guessProjectViewFromLocation(
      WorkspacePathResolver workspacePathResolver, WorkspacePath workspacePath) {

    List<WorkspacePath> workspacePaths = new ArrayList<>();
    workspacePaths.add(workspacePath);
    workspacePaths.addAll(
        RelatedWorkspacePathFinder.getInstance()
            .findRelatedWorkspaceDirectories(workspacePathResolver, workspacePath));

    ListSection.Builder<DirectoryEntry> directorySectionBuilder =
        ListSection.builder(DirectorySection.KEY);
    ListSection.Builder<TargetExpression> targetSectionBuilder =
        ListSection.builder(TargetSection.KEY);
    workspacePaths.forEach(
        path -> {
          directorySectionBuilder.add(DirectoryEntry.include(path));
          targetSectionBuilder.add(TargetExpression.allFromPackageRecursive(path));
        });

    return ProjectViewParser.projectViewToString(
        ProjectView.builder()
            .add(directorySectionBuilder)
            .add(TextBlockSection.of(TextBlock.newLine()))
            .add(targetSectionBuilder)
            .add(TextBlockSection.of(TextBlock.newLine()))
            .build());
  }

  private String getBuildFilePath() {
    return buildFilePathField.getText().trim();
  }

  private void chooseWorkspacePath() {
    BuildSystemProvider buildSystem =
        BuildSystemProvider.getBuildSystemProvider(builder.getBuildSystem());
    assert buildSystem != null;
    FileChooserDescriptor descriptor =
        new FileChooserDescriptor(true, false, false, false, false, false)
            .withShowHiddenFiles(true) // Show root project view file
            .withHideIgnored(false)
            .withTitle("Select BUILD File")
            .withDescription("Select a BUILD file to synthesize a project view from.")
            .withFileFilter(virtualFile -> buildSystem.isBuildFile(virtualFile.getName()));
    FileChooserDialog chooser =
        FileChooserFactory.getInstance().createFileChooser(descriptor, null, null);

    WorkspacePathResolver workspacePathResolver =
        builder.getWorkspaceOption().getWorkspacePathResolver();

    File fileBrowserRoot = builder.getWorkspaceOption().getFileBrowserRoot();
    File startingLocation = fileBrowserRoot;
    String buildFilePath = getBuildFilePath();
    if (!buildFilePath.isEmpty() && WorkspacePath.validate(buildFilePath)) {
      // If the user has typed part of the path then clicked the '...', try to start from the
      // partial state
      buildFilePath = StringUtil.trimEnd(buildFilePath, '/');
      if (WorkspacePath.validate(buildFilePath)) {
        File fileLocation = workspacePathResolver.resolveToFile(new WorkspacePath(buildFilePath));
        if (fileLocation.exists() && FileUtil.isAncestor(fileBrowserRoot, fileLocation, true)) {
          startingLocation = fileLocation;
        }
      }
    }
    VirtualFile toSelect =
        LocalFileSystem.getInstance().refreshAndFindFileByPath(startingLocation.getPath());
    VirtualFile[] files = chooser.choose(null, toSelect);
    if (files.length == 0) {
      return;
    }
    VirtualFile file = files[0];

    if (!FileUtil.isAncestor(fileBrowserRoot.getPath(), file.getPath(), true)) {
      Messages.showErrorDialog(
          String.format("You must choose a BUILD file under %s.", fileBrowserRoot.getPath()),
          "Cannot Use BUILD File");
      return;
    }

    String newWorkspacePath = FileUtil.getRelativePath(fileBrowserRoot, new File(file.getPath()));
    buildFilePathField.setText(newWorkspacePath);
  }
}
