// 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.devtools.bazel.e4b.wizard;

import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;

import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;

import com.google.common.collect.ImmutableList;
import com.google.devtools.bazel.e4b.Activator;
import com.google.devtools.bazel.e4b.command.BazelNotFoundException;

/**
 * This is a quick wizard page that ask the user for the various targets and source path he wants to
 * include.
 */
public class WorkspaceWizardPage extends WizardPage {

  private Label workspaceRoot;
  private List targets;
  private Text target;
  private Button addTargetButton;
  private Button removeTargetButton;
  private CheckboxTreeViewer directories;
  private Composite container;
  private Button workspaceRootButton;
  private DirectoryDialog dialog;
  private BazelTargetCompletionContentProposalProvider completionProvider;

  protected WorkspaceWizardPage() {
    super("Import Bazel project");
    setTitle("Import Bazel project");
  }

  /**
   * Returns the list of targets selected by the user.
   */
  ImmutableList<String> getTargets() {
    return ImmutableList.copyOf(targets.getItems());
  }

  /**
   * Returns the list of directories selected by the user.
   */
  ImmutableList<String> getDirectories() {
    return DirectoryTreeContentProvider.getSelectPathsRelativeToRoot(directories);
  }

  /**
   * Returns the workspace root selected by the user.
   */
  public String getWorkspaceRoot() {
    return workspaceRoot.getText();
  }

  /**
   * Returns the language version for the new project.
   */
  int getJavaLanguageVersion() {
    return 8;
  }


  @Override
  public void createControl(Composite parent) {
    container = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.numColumns = 3;
    container.setLayout(layout);

    createWorkspaceSelectionControls();

    addLabel("Directories: ", 1, 5);
    directories = DirectoryTreeContentProvider.createTreeView(container);
    setControlGridData(directories.getTree(), 2, 5, true);
    directories.addCheckStateListener(e -> updateControls());

    new Label(container, SWT.NONE).setText("Targets:");
    createTargetTextField();
    setControlGridData(target, 1, 1, false);
    addTargetButton = createButton("+", e -> addTarget());

    targets = new List(container, SWT.SINGLE | SWT.BORDER);
    setControlGridData(targets, 2, 5, true);
    removeTargetButton = createButton("-", e -> deleteTarget());
    targets.addSelectionListener(createSelectionListener(
        e -> removeTargetButton.setEnabled(targets.getSelectionCount() > 0)));

    setControl(container);
    updateControls();
  }

  // A simple helper to use lambdas to create a SelectionListener that does the same action on all
  // cases.
  private static SelectionListener createSelectionListener(Consumer<SelectionEvent> f) {
    return new SelectionListener() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        f.accept(e);

      }

      @Override
      public void widgetDefaultSelected(SelectionEvent e) {
        f.accept(e);
      }
    };
  }

  private Button createButton(String text, Consumer<SelectionEvent> handler) {
    Button result = new Button(container, SWT.DEFAULT);
    result.setText(text);
    result.addSelectionListener(createSelectionListener(handler));
    result.setEnabled(false);
    return result;
  }

  private void createWorkspaceSelectionControls() {
    Label label = new Label(container, SWT.NONE);
    label.setText("Workpsace root: ");

    workspaceRoot = new Label(container, SWT.BORDER);
    workspaceRoot.setText("");
    workspaceRoot.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

    dialog = new DirectoryDialog(getShell(), SWT.OPEN);
    workspaceRootButton = new Button(container, SWT.DEFAULT);
    workspaceRootButton.setText("...");
    workspaceRootButton.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        String wr = dialog.open();
        if (wr != null) {
          workspaceRoot.setText(wr);
          DirectoryTreeContentProvider.setFileTreeRoot(directories, new File(wr));
          try {
            completionProvider.setBazelInstance(
                Activator.getDefault().getCommand().getInstance(new File(getWorkspaceRoot())));
          } catch (IOException e1) {
            MessageDialog.openError(getShell(), "Error",
                getWorkspaceRoot() + " does not seems to be a Bazel workspace");
          } catch (InterruptedException e1) {
            Activator.error("Bazel was interrupted", e1);
          } catch (BazelNotFoundException e1) {
            MessageDialog.openError(getShell(), "Error", "Cannot found Bazel: " + e1.getMessage());
          }

        }
        updateControls();
      }
    });
    workspaceRootButton.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
  }

  private void setControlGridData(Control control, int horizontalSpan, int verticalSpan,
      boolean verticalGrow) {
    GridData data = new GridData(GridData.FILL, verticalGrow ? GridData.FILL : GridData.CENTER,
        true, verticalGrow);
    data.horizontalSpan = horizontalSpan;
    data.verticalSpan = verticalSpan;
    control.setLayoutData(data);
  }

  private void addLabel(String labelText, int horizontalSpan, int verticalSpan) {
    Label label = new Label(container, SWT.NONE);
    label.setText(labelText);
    GridData data = new GridData(GridData.BEGINNING, GridData.FILL, false, true);
    data.horizontalSpan = horizontalSpan;
    data.verticalSpan = verticalSpan;
    label.setLayoutData(data);
  }

  private void updateControls() {
    boolean enabled = !workspaceRoot.getText().isEmpty();
    directories.getTree().setEnabled(enabled);
    targets.setEnabled(enabled);
    target.setEnabled(enabled);
    addTargetButton.setEnabled(enabled && !target.getText().isEmpty());
    removeTargetButton.setEnabled(enabled && targets.getSelectionCount() > 0);
    setPageComplete(
        enabled && (directories.getCheckedElements().length > 0) && (targets.getItemCount() > 0));
  }

  private void setAutoCompletion() {
    try {
      ContentProposalAdapter adapter = null;
      completionProvider = new BazelTargetCompletionContentProposalProvider();
      KeyStroke ks = KeyStroke.getInstance("Ctrl+Space");
      adapter = new ContentProposalAdapter(target, new TextContentAdapter(), completionProvider, ks,
          null);
      adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }


  private void createTargetTextField() {
    target = new Text(container, SWT.BORDER);
    setAutoCompletion();
    target.addKeyListener(new KeyAdapter() {
      @Override
      public void keyReleased(KeyEvent ke) {
        if (ke.keyCode == '\r' && (ke.stateMask & SWT.SHIFT) != 0 && !target.getText().isEmpty()) {
          addTarget();
        }
      }
    });
    target.addModifyListener(e -> updateControls());
  }

  private void addTarget() {
    targets.add(target.getText());
    target.setText("");
    setAutoCompletion();
    updateControls();
  }

  private void deleteTarget() {
    targets.remove(targets.getSelectionIndices());
    updateControls();
  }
}
