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

import com.android.tools.idea.run.activity.ActivityLocatorUtils;
import com.google.idea.blaze.android.run.binary.instantrun.InstantRunExperiment;
import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.ui.IntegerTextField;
import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.LanguageTextField;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ResourceBundle;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.TitledBorder;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;

/**
 * The part of the Blaze Android Binary handler editor that allows the user to pick an activity to
 * launch. Patterned after {@link org.jetbrains.android.run.ApplicationRunParameters}.
 */
class BlazeAndroidBinaryRunConfigurationStateEditor implements RunConfigurationStateEditor {
  public static final Key<BlazeAndroidBinaryRunConfigurationStateEditor>
      ACTIVITY_CLASS_TEXT_FIELD_KEY = Key.create("BlazeActivityClassTextField");

  private final RunConfigurationStateEditor commonStateEditor;

  private JPanel panel;
  private ComponentWithBrowseButton<EditorTextField> activityField;
  private JRadioButton launchNothingButton;
  private JRadioButton launchDefaultButton;
  private JRadioButton launchCustomButton;
  private JCheckBox mobileInstallCheckBox;
  private JCheckBox splitApksCheckBox;
  private JCheckBox instantRunCheckBox;
  private JCheckBox useWorkProfileIfPresentCheckBox;
  private JLabel userIdLabel;
  private IntegerTextField userIdField;

  BlazeAndroidBinaryRunConfigurationStateEditor(
      RunConfigurationStateEditor commonStateEditor, Project project) {
    this.commonStateEditor = commonStateEditor;
    setupUI(project);
    userIdField.setMinValue(0);

    activityField.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            if (!project.isInitialized()) {
              return;
            }
            // We find all Activity classes in the module for the selected variant
            // (or any of its deps).
            final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
            PsiClass activityBaseClass =
                facade.findClass(
                    AndroidUtils.ACTIVITY_BASE_CLASS_NAME, ProjectScope.getAllScope(project));
            if (activityBaseClass == null) {
              Messages.showErrorDialog(
                  panel, AndroidBundle.message("cant.find.activity.class.error"));
              return;
            }
            GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project);
            PsiClass initialSelection =
                facade.findClass(activityField.getChildComponent().getText(), searchScope);
            TreeClassChooser chooser =
                TreeClassChooserFactory.getInstance(project)
                    .createInheritanceClassChooser(
                        "Select Activity Class",
                        searchScope,
                        activityBaseClass,
                        initialSelection,
                        null);
            chooser.showDialog();
            PsiClass selClass = chooser.getSelected();
            if (selClass != null) {
              // This must be done because Android represents
              // inner static class paths differently than java.
              String qualifiedActivityName =
                  ActivityLocatorUtils.getQualifiedActivityName(selClass);
              activityField.getChildComponent().setText(qualifiedActivityName);
            }
          }
        });
    ActionListener listener = e -> activityField.setEnabled(launchCustomButton.isSelected());
    launchCustomButton.addActionListener(listener);
    launchDefaultButton.addActionListener(listener);
    launchNothingButton.addActionListener(listener);

    instantRunCheckBox.setVisible(InstantRunExperiment.INSTANT_RUN_ENABLED.getValue());

    /* Only one of mobile-install and instant run can be selected at any one time */
    mobileInstallCheckBox.addActionListener(
        e -> {
          if (mobileInstallCheckBox.isSelected()) {
            instantRunCheckBox.setSelected(false);
          }
        });
    instantRunCheckBox.addActionListener(
        e -> {
          if (instantRunCheckBox.isSelected()) {
            mobileInstallCheckBox.setSelected(false);
          }
        });

    mobileInstallCheckBox.addActionListener(
        e -> splitApksCheckBox.setVisible(mobileInstallCheckBox.isSelected()));

    useWorkProfileIfPresentCheckBox.addActionListener(
        e -> {
          setUserIdEnabled(!useWorkProfileIfPresentCheckBox.isSelected());
        });
  }

  @Override
  public void resetEditorFrom(RunConfigurationState genericState) {
    BlazeAndroidBinaryRunConfigurationState state =
        (BlazeAndroidBinaryRunConfigurationState) genericState;
    commonStateEditor.resetEditorFrom(state.getCommonState());
    boolean launchSpecificActivity =
        state.getMode().equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
    if (state.getMode().equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY)) {
      launchDefaultButton.setSelected(true);
    } else if (launchSpecificActivity) {
      launchCustomButton.setSelected(true);
    } else {
      launchNothingButton.setSelected(true);
    }
    activityField.setEnabled(launchSpecificActivity);
    if (launchSpecificActivity) {
      activityField.getChildComponent().setText(state.getActivityClass());
    }

    mobileInstallCheckBox.setSelected(state.mobileInstall());
    splitApksCheckBox.setSelected(state.useSplitApksIfPossible());
    instantRunCheckBox.setSelected(state.instantRun());
    useWorkProfileIfPresentCheckBox.setSelected(state.useWorkProfileIfPresent());

    userIdField.setValue(state.getUserId());
    setUserIdEnabled(!state.useWorkProfileIfPresent());
    splitApksCheckBox.setVisible(state.mobileInstall());
  }

  private void setUserIdEnabled(boolean enabled) {
    userIdLabel.setEnabled(enabled);
    userIdField.setEnabled(enabled);
  }

  @Override
  public void applyEditorTo(RunConfigurationState genericState) {
    BlazeAndroidBinaryRunConfigurationState state =
        (BlazeAndroidBinaryRunConfigurationState) genericState;
    commonStateEditor.applyEditorTo(state.getCommonState());

    state.setUserId((Integer) userIdField.getValue());
    if (launchDefaultButton.isSelected()) {
      state.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY);
    } else if (launchCustomButton.isSelected()) {
      state.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
      state.setActivityClass(activityField.getChildComponent().getText());
    } else {
      state.setMode(BlazeAndroidBinaryRunConfigurationState.DO_NOTHING);
    }
    state.setMobileInstall(mobileInstallCheckBox.isSelected());
    state.setUseSplitApksIfPossible(splitApksCheckBox.isSelected());
    state.setInstantRun(instantRunCheckBox.isSelected());
    state.setUseWorkProfileIfPresent(useWorkProfileIfPresentCheckBox.isSelected());
  }

  @Override
  public JComponent createComponent() {
    return UiUtil.createBox(commonStateEditor.createComponent(), panel);
  }

  private void createUIComponents(Project project) {
    final EditorTextField editorTextField =
        new LanguageTextField(PlainTextLanguage.INSTANCE, project, "") {
          @Override
          protected EditorEx createEditor() {
            final EditorEx editor = super.createEditor();
            final PsiFile file =
                PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());

            if (file != null) {
              DaemonCodeAnalyzer.getInstance(project).setHighlightingEnabled(file, false);
            }
            editor.putUserData(
                ACTIVITY_CLASS_TEXT_FIELD_KEY, BlazeAndroidBinaryRunConfigurationStateEditor.this);
            return editor;
          }
        };
    activityField = new ComponentWithBrowseButton<EditorTextField>(editorTextField, null);
  }

  /** Initially generated by IntelliJ from a .form file, then checked in as source. */
  private void setupUI(Project project) {
    createUIComponents(project);
    panel = new JPanel();
    panel.setLayout(new GridLayoutManager(5, 2, new Insets(0, 0, 0, 0), -1, -1));
    final JPanel activityPanel = new JPanel();
    activityPanel.setLayout(new GridLayoutManager(4, 2, new Insets(0, 0, 0, 0), -1, -1));
    panel.add(
        activityPanel,
        new GridConstraints(
            3,
            0,
            1,
            2,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null,
            0,
            false));
    activityPanel.setBorder(
        BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(),
            "Activity",
            TitledBorder.DEFAULT_JUSTIFICATION,
            TitledBorder.DEFAULT_POSITION,
            new Font(
                activityPanel.getFont().getName(),
                activityPanel.getFont().getStyle(),
                activityPanel.getFont().getSize()),
            new Color(-16777216)));
    final JPanel userPanel = new JPanel();
    userPanel.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), -1, -1));
    panel.add(
        userPanel,
        new GridConstraints(
            4,
            0,
            1,
            2,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            null,
            null,
            null,
            0,
            false));
    userPanel.setBorder(
        BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(),
            "User",
            TitledBorder.DEFAULT_JUSTIFICATION,
            TitledBorder.DEFAULT_POSITION,
            new Font(
                userPanel.getFont().getName(),
                userPanel.getFont().getStyle(),
                userPanel.getFont().getSize()),
            new Color(-16777216)));
    launchNothingButton = new JRadioButton();
    this.loadButtonText(
        launchNothingButton,
        ResourceBundle.getBundle("messages/AndroidBundle")
            .getString("android.run.configuration.do.nothing.label"));
    activityPanel.add(
        launchNothingButton,
        new GridConstraints(
            0,
            0,
            1,
            2,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    launchDefaultButton = new JRadioButton();
    launchDefaultButton.setText("Launch default Activity");
    launchDefaultButton.setMnemonic('L');
    launchDefaultButton.setDisplayedMnemonicIndex(0);
    activityPanel.add(
        launchDefaultButton,
        new GridConstraints(
            1,
            0,
            1,
            2,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    launchCustomButton = new JRadioButton();
    launchCustomButton.setText("Launch:");
    launchCustomButton.setMnemonic('A');
    launchCustomButton.setDisplayedMnemonicIndex(1);
    activityPanel.add(
        launchCustomButton,
        new GridConstraints(
            2,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    activityPanel.add(
        activityField,
        new GridConstraints(
            2,
            1,
            1,
            1,
            GridConstraints.ANCHOR_CENTER,
            GridConstraints.FILL_BOTH,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    useWorkProfileIfPresentCheckBox = new JCheckBox();
    useWorkProfileIfPresentCheckBox.setText(" Use work profile if present");
    userPanel.add(
        useWorkProfileIfPresentCheckBox,
        new GridConstraints(
            0,
            0,
            1,
            2,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    userIdLabel = new JLabel();
    userIdLabel.setText("User ID");
    userPanel.add(
        userIdLabel,
        new GridConstraints(
            1,
            0,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_FIXED,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            1,
            false));
    userIdField = new IntegerTextField();
    userPanel.add(
        userIdField,
        new GridConstraints(
            1,
            1,
            1,
            1,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_HORIZONTAL,
            GridConstraints.SIZEPOLICY_WANT_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    mobileInstallCheckBox = new JCheckBox();
    mobileInstallCheckBox.setText(" Use mobile-install");
    panel.add(
        mobileInstallCheckBox,
        new GridConstraints(
            0,
            0,
            1,
            2,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    splitApksCheckBox = new JCheckBox();
    splitApksCheckBox.setText(" Use --split_apks where possible");
    panel.add(
        splitApksCheckBox,
        new GridConstraints(
            1,
            0,
            1,
            2,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    instantRunCheckBox = new JCheckBox();
    instantRunCheckBox.setText(" Use InstantRun");
    panel.add(
        instantRunCheckBox,
        new GridConstraints(
            2,
            0,
            1,
            2,
            GridConstraints.ANCHOR_WEST,
            GridConstraints.FILL_NONE,
            GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
            GridConstraints.SIZEPOLICY_FIXED,
            null,
            null,
            null,
            0,
            false));
    ButtonGroup buttonGroup;
    buttonGroup = new ButtonGroup();
    buttonGroup.add(launchDefaultButton);
    buttonGroup.add(launchCustomButton);
    buttonGroup.add(launchNothingButton);
  }

  /** Initially generated by IntelliJ from a .form file. */
  private void loadButtonText(AbstractButton component, String text) {
    StringBuffer result = new StringBuffer();
    boolean haveMnemonic = false;
    char mnemonic = '\0';
    int mnemonicIndex = -1;
    for (int i = 0; i < text.length(); i++) {
      if (text.charAt(i) == '&') {
        i++;
        if (i == text.length()) {
          break;
        }
        if (!haveMnemonic && text.charAt(i) != '&') {
          haveMnemonic = true;
          mnemonic = text.charAt(i);
          mnemonicIndex = result.length();
        }
      }
      result.append(text.charAt(i));
    }
    component.setText(result.toString());
    if (haveMnemonic) {
      component.setMnemonic(mnemonic);
      component.setDisplayedMnemonicIndex(mnemonicIndex);
    }
  }
}
