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

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.ProjectViewSet.ProjectViewFile;
import com.google.idea.blaze.base.run.BlazeRunConfiguration;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.BooleanTableCellEditor;
import com.intellij.ui.BooleanTableCellRenderer;
import com.intellij.ui.ColoredTableCellRenderer;
import com.intellij.ui.FieldPanel;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.table.JBTable;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/** UI for exporting blaze run configurations. */
public class ExportRunConfigurationDialog extends DialogWrapper {

  private final ImmutableList<RunConfiguration> blazeConfigurations;
  private final ExportRunConfigurationTableModel tableModel;
  private final JBTable table;
  private final FieldPanel outputDirectoryPanel;

  ExportRunConfigurationDialog(Project project) {
    super(project, true);
    blazeConfigurations =
        ImmutableList.copyOf(
            RunManager.getInstance(project)
                .getAllConfigurationsList()
                .stream()
                .filter((config) -> config instanceof BlazeRunConfiguration)
                .collect(Collectors.toList()));
    tableModel = new ExportRunConfigurationTableModel(blazeConfigurations);
    table = new JBTable(tableModel);

    TableColumn booleanColumn = table.getColumnModel().getColumn(0);
    booleanColumn.setCellRenderer(new BooleanTableCellRenderer());
    booleanColumn.setCellEditor(new BooleanTableCellEditor());
    int width = table.getFontMetrics(table.getFont()).stringWidth(table.getColumnName(0)) + 10;
    booleanColumn.setPreferredWidth(width);
    booleanColumn.setMinWidth(width);
    booleanColumn.setMaxWidth(width);

    table
        .getColumnModel()
        .getColumn(2)
        .setCellEditor(new DefaultCellEditor(GuiUtils.createUndoableTextField()));

    TableColumn nameColumn = table.getColumnModel().getColumn(1);
    nameColumn.setCellRenderer(
        new ColoredTableCellRenderer() {
          @Override
          protected void customizeCellRenderer(
              JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
            RunConfiguration config = blazeConfigurations.get(row);
            setIcon(config.getType().getIcon());
            append(config.getName());
          }
        });

    table.setPreferredSize(new Dimension(700, 700));
    table.setShowColumns(true);

    final ActionListener browseAction = e -> chooseDirectory();
    outputDirectoryPanel =
        new FieldPanel("Export configurations to directory:", null, browseAction, null);
    File defaultExportDirectory = defaultExportDirectory(project);
    if (defaultExportDirectory != null) {
      outputDirectoryPanel.setText(defaultExportDirectory.getPath());
    }

    String buildSystem = Blaze.buildSystemName(project);
    setTitle(String.format("Export %s Run Configurations", buildSystem));
    init();
  }

  /** Try to find a checked-in project view file. Otherwise, fall back to the workspace root. */
  @Nullable
  private static File defaultExportDirectory(Project project) {
    WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProjectSafe(project);
    if (workspaceRoot == null) {
      return null;
    }
    ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
    if (projectViewSet != null) {
      for (ProjectViewFile projectViewFile : projectViewSet.getProjectViewFiles()) {
        File file = projectViewFile.projectViewFile;
        if (file != null && FileUtil.isAncestor(workspaceRoot.directory(), file, false)) {
          return file.getParentFile();
        }
      }
    }
    return workspaceRoot.directory();
  }

  private String getOutputDirectoryPath() {
    return Strings.nullToEmpty(outputDirectoryPanel.getText()).trim();
  }

  private void chooseDirectory() {
    FileChooserDescriptor descriptor =
        FileChooserDescriptorFactory.createSingleFolderDescriptor()
            .withTitle("Export Directory Location")
            .withDescription("Choose directory to export run configurations to")
            .withHideIgnored(false);
    FileChooserDialog chooser =
        FileChooserFactory.getInstance().createFileChooser(descriptor, null, null);

    final VirtualFile[] files;
    File existingLocation = new File(getOutputDirectoryPath());
    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];
    outputDirectoryPanel.setText(file.getPath());
  }

  @Nullable
  @Override
  protected ValidationInfo doValidate() {
    String outputDir = getOutputDirectoryPath();
    if (outputDir.isEmpty()) {
      return new ValidationInfo("Choose an output directory");
    }
    if (!FileAttributeProvider.getInstance().exists(new File(outputDir))) {
      return new ValidationInfo("Invalid output directory");
    }
    Set<String> names = new HashSet<>();
    for (int i = 0; i < blazeConfigurations.size(); i++) {
      if (!tableModel.enabled[i]) {
        continue;
      }
      if (!names.add(tableModel.paths[i])) {
        return new ValidationInfo("Duplicate output file name '" + tableModel.paths[i] + "'");
      }
    }
    return null;
  }

  @Override
  protected void doOKAction() {
    File outputDir = new File(getOutputDirectoryPath());
    List<File> outputFiles = new ArrayList<>();
    for (int i = 0; i < blazeConfigurations.size(); i++) {
      if (!tableModel.enabled[i]) {
        continue;
      }
      File outputFile = new File(outputDir, tableModel.paths[i]);
      writeConfiguration(blazeConfigurations.get(i), outputFile);
      outputFiles.add(outputFile);
    }
    LocalFileSystem.getInstance().refreshIoFiles(outputFiles);
    super.doOKAction();
  }

  private static void writeConfiguration(RunConfiguration configuration, File outputFile) {
    try (FileOutputStream writer = new FileOutputStream(outputFile, false)) {
      XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
      xmlOutputter.output(RunConfigurationSerializer.writeToXml(configuration), writer);
    } catch (IOException e) {
      throw new RuntimeException("Error exporting run configuration to file: " + outputFile);
    }
  }

  @Override
  protected JComponent createNorthPanel() {
    return outputDirectoryPanel;
  }

  @Override
  protected JComponent createCenterPanel() {
    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(IdeBorderFactory.createTitledBorder("Run Configurations", false));
    panel.add(
        ToolbarDecorator.createDecorator(table).addExtraAction(new SelectAllButton()).createPanel(),
        BorderLayout.CENTER);
    return panel;
  }

  private class SelectAllButton extends AnActionButton {

    boolean allSelected = false;

    private SelectAllButton() {
      super("Select All", AllIcons.Actions.Selectall);
    }

    @Override
    public synchronized void actionPerformed(AnActionEvent anActionEvent) {
      boolean newState = !allSelected;
      for (int i = 0; i < tableModel.enabled.length; i++) {
        table.setValueAt(newState, i, 0);
      }
      allSelected = newState;
      Presentation presentation = anActionEvent.getPresentation();
      if (allSelected) {
        presentation.setText("Deselect All");
        presentation.setIcon(AllIcons.Actions.Unselectall);
      } else {
        presentation.setText("Select All");
        presentation.setIcon(AllIcons.Actions.Selectall);
      }
      tableModel.fireTableDataChanged();
      table.revalidate();
      table.repaint();
    }
  }
}
