/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.netbeans.modules.micronaut.newproject;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.net.MalformedURLException;
import java.net.URL;
import javax.lang.model.SourceVersion;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.openide.WizardDescriptor;
import org.openide.WizardValidationException;
import org.openide.util.AsyncGUIJob;
import org.openide.util.RequestProcessor;

/**
 * Options panel for the Base Properties step in Micronaut project wizard.
 *
 * @author Dusan Balek
 */
public class BasePropertiesVisual extends JPanel implements DocumentListener, ActionListener, AsyncGUIJob {

    private final BasePropertiesWizardPanel panel;
    private boolean initialized = false;
    private boolean failed = false;

    public BasePropertiesVisual(BasePropertiesWizardPanel panel) {
        initComponents();
        this.panel = panel;
        this.defaultRadioButton.addActionListener(this);
        this.snapshotRadioButton.addActionListener(this);
        this.customRadioButton.addActionListener(this);
        this.customTextField.getDocument().addDocumentListener(this);
        this.groupTextField.getDocument().addDocumentListener(this);
        this.versionTextField.getDocument().addDocumentListener(this);
        this.customTextField.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                customRadioButton.setSelected(true);
                versionTextField.setText("");
                applicationTypeComboBox.removeAllItems();
                javaVersionComboBox.removeAllItems();
            }
            @Override
            public void focusLost(FocusEvent e) {
                if (customRadioButton.isSelected()) {
                    if (customURLValid()) {
                        refresh();
                    } else {
                        panel.fireChangeEvent();
                    }
                }
            }
        });
    }

    /**
     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of
     * this method is always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        serviceButtonGroup = new javax.swing.ButtonGroup();
        languageButtonGroup = new javax.swing.ButtonGroup();
        testFrameworkButtonGroup = new javax.swing.ButtonGroup();
        serviceURLLabel = new javax.swing.JLabel();
        defaultRadioButton = new javax.swing.JRadioButton();
        defaultURLLabel = new javax.swing.JLabel();
        snapshotRadioButton = new javax.swing.JRadioButton();
        snapshotURLLabel = new javax.swing.JLabel();
        customRadioButton = new javax.swing.JRadioButton();
        customTextField = new javax.swing.JTextField();
        versionLabel = new javax.swing.JLabel();
        versionTextField = new javax.swing.JTextField();
        groupLabel = new javax.swing.JLabel();
        groupTextField = new javax.swing.JTextField();
        artifactLabel = new javax.swing.JLabel();
        artifactTextField = new javax.swing.JTextField();
        applicationTypeLabel = new javax.swing.JLabel();
        applicationTypeComboBox = new javax.swing.JComboBox<>();
        javaVersionLabel = new javax.swing.JLabel();
        javaVersionComboBox = new javax.swing.JComboBox<>();
        languageLabel = new javax.swing.JLabel();
        javaRadioButton = new javax.swing.JRadioButton();
        kotlinRadioButton = new javax.swing.JRadioButton();
        groovyRadioButton = new javax.swing.JRadioButton();
        testFrameworkLabel = new javax.swing.JLabel();
        junitRadioButton = new javax.swing.JRadioButton();
        spockRadioButton = new javax.swing.JRadioButton();
        kotestRadioButton = new javax.swing.JRadioButton();

        org.openide.awt.Mnemonics.setLocalizedText(serviceURLLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_ChooseServiceURL")); // NOI18N

        serviceButtonGroup.add(defaultRadioButton);
        defaultRadioButton.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(defaultRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Default")); // NOI18N
        defaultRadioButton.setActionCommand("DEFAULT");

        defaultURLLabel.setFont(new java.awt.Font("Dialog", 2, 12)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(defaultURLLabel, MicronautLaunchService.defaultURL);

        serviceButtonGroup.add(snapshotRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(snapshotRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Snapshot")); // NOI18N
        snapshotRadioButton.setActionCommand("SNAPSHOT");

        snapshotURLLabel.setFont(new java.awt.Font("Dialog", 2, 12)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(snapshotURLLabel, MicronautLaunchService.snapshotURL);

        serviceButtonGroup.add(customRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(customRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Custom")); // NOI18N
        customRadioButton.setActionCommand("CUSTOM");

        org.openide.awt.Mnemonics.setLocalizedText(versionLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Version")); // NOI18N

        versionTextField.setEditable(false);
        versionTextField.setColumns(20);

        groupLabel.setLabelFor(groupTextField);
        org.openide.awt.Mnemonics.setLocalizedText(groupLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Group")); // NOI18N

        groupTextField.setColumns(20);

        artifactLabel.setLabelFor(artifactTextField);
        org.openide.awt.Mnemonics.setLocalizedText(artifactLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Artifact")); // NOI18N

        artifactTextField.setEditable(false);
        artifactTextField.setColumns(20);

        applicationTypeLabel.setLabelFor(applicationTypeComboBox);
        org.openide.awt.Mnemonics.setLocalizedText(applicationTypeLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_ApplicationType")); // NOI18N

        javaVersionLabel.setLabelFor(javaVersionComboBox);
        org.openide.awt.Mnemonics.setLocalizedText(javaVersionLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_JavaVersion")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(languageLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Language")); // NOI18N

        languageButtonGroup.add(javaRadioButton);
        javaRadioButton.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(javaRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Java")); // NOI18N
        javaRadioButton.setActionCommand("JAVA");

        languageButtonGroup.add(kotlinRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(kotlinRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Kotlin")); // NOI18N
        kotlinRadioButton.setActionCommand("KOTLIN");

        languageButtonGroup.add(groovyRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(groovyRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Groovy")); // NOI18N
        groovyRadioButton.setActionCommand("GROOVY");

        org.openide.awt.Mnemonics.setLocalizedText(testFrameworkLabel, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_TestFramework")); // NOI18N

        testFrameworkButtonGroup.add(junitRadioButton);
        junitRadioButton.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(junitRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_JUnit")); // NOI18N
        junitRadioButton.setActionCommand("JUNIT");

        testFrameworkButtonGroup.add(spockRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(spockRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Spock")); // NOI18N
        spockRadioButton.setActionCommand("SPOCK");

        testFrameworkButtonGroup.add(kotestRadioButton);
        org.openide.awt.Mnemonics.setLocalizedText(kotestRadioButton, org.openide.util.NbBundle.getMessage(BasePropertiesVisual.class, "LBL_Kotest")); // NOI18N
        kotestRadioButton.setActionCommand("KOTEST");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(javaVersionLabel)
                    .addComponent(groupLabel)
                    .addComponent(languageLabel)
                    .addComponent(customRadioButton)
                    .addComponent(artifactLabel)
                    .addComponent(applicationTypeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(versionLabel)
                    .addComponent(snapshotRadioButton)
                    .addComponent(defaultRadioButton)
                    .addComponent(serviceURLLabel)
                    .addComponent(testFrameworkLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(javaVersionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(javaRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(junitRadioButton))
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(spockRadioButton)
                                    .addComponent(kotlinRadioButton))
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(groovyRadioButton)
                                    .addComponent(kotestRadioButton))))
                        .addGap(357, 357, 357))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(defaultURLLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(versionTextField)
                            .addComponent(snapshotURLLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(customTextField)
                            .addComponent(applicationTypeComboBox, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(artifactTextField, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(groupTextField))
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(serviceURLLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(defaultRadioButton)
                    .addComponent(defaultURLLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(snapshotRadioButton)
                    .addComponent(snapshotURLLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(customRadioButton)
                    .addComponent(customTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(versionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(versionLabel))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(groupTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(groupLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(artifactTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(artifactLabel))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(applicationTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(applicationTypeLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(javaVersionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(javaVersionLabel))
                .addGap(4, 4, 4)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(languageLabel)
                    .addComponent(javaRadioButton)
                    .addComponent(kotlinRadioButton)
                    .addComponent(groovyRadioButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(testFrameworkLabel)
                    .addComponent(junitRadioButton)
                    .addComponent(spockRadioButton)
                    .addComponent(kotestRadioButton))
                .addContainerGap(28, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox<MicronautLaunchService.ApplicationType> applicationTypeComboBox;
    private javax.swing.JLabel applicationTypeLabel;
    private javax.swing.JLabel artifactLabel;
    private javax.swing.JTextField artifactTextField;
    private javax.swing.JRadioButton customRadioButton;
    private javax.swing.JTextField customTextField;
    private javax.swing.JRadioButton defaultRadioButton;
    private javax.swing.JLabel defaultURLLabel;
    private javax.swing.JRadioButton groovyRadioButton;
    private javax.swing.JLabel groupLabel;
    private javax.swing.JTextField groupTextField;
    private javax.swing.JRadioButton javaRadioButton;
    private javax.swing.JComboBox<String> javaVersionComboBox;
    private javax.swing.JLabel javaVersionLabel;
    private javax.swing.JRadioButton junitRadioButton;
    private javax.swing.JRadioButton kotestRadioButton;
    private javax.swing.JRadioButton kotlinRadioButton;
    private javax.swing.ButtonGroup languageButtonGroup;
    private javax.swing.JLabel languageLabel;
    private javax.swing.ButtonGroup serviceButtonGroup;
    private javax.swing.JLabel serviceURLLabel;
    private javax.swing.JRadioButton snapshotRadioButton;
    private javax.swing.JLabel snapshotURLLabel;
    private javax.swing.JRadioButton spockRadioButton;
    private javax.swing.ButtonGroup testFrameworkButtonGroup;
    private javax.swing.JLabel testFrameworkLabel;
    private javax.swing.JLabel versionLabel;
    private javax.swing.JTextField versionTextField;
    // End of variables declaration//GEN-END:variables

    boolean valid(WizardDescriptor wizardDescriptor) {
        if (failed) {
            wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Problems in contacting service!");
            return false;
        }
        if (groupTextField.getText().isEmpty()) {
            wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Group can't be empty.");
            return false;
        }
        if (!SourceVersion.isName(groupTextField.getText())) {
            wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Not a valid Group name.");
            return false;
        }
        if (customRadioButton.isSelected()) {
            if (customTextField.getText().isEmpty()) {
                wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Service URL can't be empty.");
                return false;
            }
            if (!customURLValid()) {
                wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Not a valid Service URL.");
                return false;
            }
        }
        wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "");
        return !versionTextField.getText().isEmpty();
    }

    void store(WizardDescriptor wd) {
        wd.putProperty(MicronautProjectWizardIterator.SERVICE_URL, getServiceUrl());
        wd.putProperty(MicronautProjectWizardIterator.MAVEN_GROUP, groupTextField.getText().trim());
        wd.putProperty(MicronautProjectWizardIterator.APPLICATION_TYPE, applicationTypeComboBox.getSelectedItem());
        wd.putProperty(MicronautProjectWizardIterator.JAVA_VERSION, javaVersionComboBox.getSelectedItem());
        wd.putProperty(MicronautProjectWizardIterator.LANGUAGE, languageButtonGroup.getSelection().getActionCommand());
        wd.putProperty(MicronautProjectWizardIterator.TEST_FRAMEWORK, testFrameworkButtonGroup.getSelection().getActionCommand());
    }

    void read(WizardDescriptor wd) {
        String serviceUrl = (String) wd.getProperty(MicronautProjectWizardIterator.SERVICE_URL);
        if (serviceUrl != null) {
            switch (serviceUrl) {
                case MicronautLaunchService.defaultURL:
                    this.defaultRadioButton.setSelected(true);
                    break;
                case MicronautLaunchService.snapshotURL:
                    this.snapshotRadioButton.setSelected(true);
                    break;
                default:
                    this.customTextField.setText(serviceUrl);
            }
        }
        String group = (String) wd.getProperty(MicronautProjectWizardIterator.MAVEN_GROUP);
        this.groupTextField.setText(group == null || group.isEmpty() ? "com.example" : group);
        this.artifactTextField.setText((String) wd.getProperty(MicronautProjectWizardIterator.MAVEN_ARTIFACT));
        javaVersionComboBox.setSelectedItem(MicronautProjectWizardIterator.JAVA_VERSION);
        applicationTypeComboBox.setSelectedItem(wd.getProperty(MicronautProjectWizardIterator.APPLICATION_TYPE));
    }

    void validate(WizardDescriptor d) throws WizardValidationException {
        // nothing to validate
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        panel.fireChangeEvent();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        panel.fireChangeEvent();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        panel.fireChangeEvent();
    }

    @Override
    public void construct() {
        try {
            panel.wizardDescriptor.putProperty(WizardDescriptor.PROP_INFO_MESSAGE, "Contacting service...");
            MicronautLaunchService service = MicronautLaunchService.getInstance();
            String serviceUrl = getServiceUrl();
            String micronautVersion = service.getMicronautVersion(serviceUrl);
            for (MicronautLaunchService.ApplicationType type : service.getApplicationTypes(serviceUrl)) {
                applicationTypeComboBox.addItem(type);
            }
            for (String version : service.getJdkVersions(serviceUrl)) {
                javaVersionComboBox.addItem(version);
            }
            versionTextField.setText(micronautVersion);
            initialized = true;
        } catch (Exception ex) {
            panel.wizardDescriptor.putProperty(WizardDescriptor.PROP_ERROR_MESSAGE, "Could not query Micronaut Launch service");
            failed = true;
            panel.fireChangeEvent();
        }
    }

    @Override
    public void finished() {
        if (initialized) {
            panel.fireChangeEvent();
            groupTextField.requestFocus();
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        versionTextField.setText("");
        applicationTypeComboBox.removeAllItems();
        javaVersionComboBox.removeAllItems();
        if ("CUSTOM".equals(e.getActionCommand())) {
            customTextField.requestFocus();
        } else {
            refresh();
        }
    }

    private void refresh() {
        initialized = false;
        failed = false;
        RequestProcessor.getDefault().post(() -> {
            construct();
            SwingUtilities.invokeLater(() -> {
                finished();
            });
        });
    }

    private String getServiceUrl() {
        switch (serviceButtonGroup.getSelection().getActionCommand()) {
            case "DEFAULT":
                return MicronautLaunchService.defaultURL;
            case "SNAPSHOT":
                return MicronautLaunchService.snapshotURL;
            default:
                return customTextField.getText();
        }
    }

    private boolean customURLValid() {
        try {
            new URL(customTextField.getText());
        } catch (MalformedURLException ex) {
            return false;
        }
        return true;
    }
}
