/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2021 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.jboss.installer.screens;

import org.jboss.installer.common.FileChooserPanel;
import org.jboss.installer.core.InstallationData;
import org.jboss.installer.core.LanguageUtils;
import org.jboss.installer.core.Screen;
import org.jboss.installer.core.ValidationResult;
import org.jboss.installer.postinstall.task.QuickstartsTask;
import org.jboss.installer.validators.MavenRepositoryValidator;
import org.jboss.installer.validators.MavenSettingsPathValidator;

import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

import static javax.swing.JFileChooser.DIRECTORIES_ONLY;
import static javax.swing.JFileChooser.FILES_AND_DIRECTORIES;

public class QuickstartsMavenRepositorySetupScreen extends DefaultScreen{

    public static final String NAME = "QuickstartsMavenRepositorySetupScreen";
    public static final String TITLE_KEY = "quickstarts.maven.setup.title";
    public static final String SIDE_NAV_KEY = "quickstarts.maven.setup.side_nav_name";
    public static final String DESCRIPTION_KEY = "quickstarts.maven.setup.description";
    public static final String VERSIONS_KEY = "quickstarts.maven.setup.versions";
    public static final String MAVEN_REPO_LABEL_KEY = "quickstarts.maven.setup.maven_repo_location";
    public static final String PUBLIC_MAVEN_REPO_KEY = "quickstarts.maven.setup.public_maven_repo";
    public static final String LOCAL_MAVEN_REPO_KEY = "quickstarts.maven.setup.local_maven_repo";
    public static final String MAVEN_SETTINGS_LABEL_KEY = "quickstarts.maven.setup.maven_settings_file";
    public static final String DEFAULT_MAVEN_SETTINGS_KEY = "quickstarts.maven.setup.default_maven_settings";
    public static final String ALTERNATIVE_MAVEN_SETTINGS_KEY = "quickstarts.maven.setup.alternative_maven_settings";
    protected static final String XML_FILES_FILTER_KEY = "quickstarts.maven.setup.maven_settings_file.filter";
    public static final String DEFAULT_MAVEN_REPOSITORY = "https://maven.repository.redhat.com/ga/";
    public static final String DEFAULT_SETTINGS_PATH = HOME_DIR + "/.m2/settings.xml";

    private final JTextArea mainDescription = createDescription(DESCRIPTION_KEY);
    private final JLabel versionsLabel = createFieldLabel(VERSIONS_KEY);
    private final JLabel mavenRepoLabel = createFieldLabel(MAVEN_REPO_LABEL_KEY);
    private final JRadioButton publicMavenRepo = createRadioButton(langUtils.getString(PUBLIC_MAVEN_REPO_KEY), true);
    private final JRadioButton localMavenRepo = createRadioButton(langUtils.getString(LOCAL_MAVEN_REPO_KEY), false);
    private final JLabel mavenSettingsLabel = createFieldLabel(MAVEN_SETTINGS_LABEL_KEY);
    private final JRadioButton defaultMavenSettings = createRadioButton(langUtils.getString(DEFAULT_MAVEN_SETTINGS_KEY, HOME_DIR), true);
    private final JRadioButton alternativeMavenSettings = createRadioButton(langUtils.getString(ALTERNATIVE_MAVEN_SETTINGS_KEY), false);
    private final QuickstartsTask quickstartsTask = new QuickstartsTask();
    private final FileChooserPanel repoFileChooser = FileChooserPanel.builder(langUtils, DIRECTORIES_ONLY, mnemonicUtils)
            .baseFolder(DEFAULT_MAVEN_REPOSITORY).build();
    private final FileChooserPanel settingsFileChooser;

    public QuickstartsMavenRepositorySetupScreen(Screen parent, LanguageUtils langUtils, boolean isActive) {
        super(parent, langUtils, isActive);
        settingsFileChooser = FileChooserPanel.builder(langUtils, FILES_AND_DIRECTORIES, mnemonicUtils)
                .baseFolder(DEFAULT_SETTINGS_PATH)
                .fileFilter(new FileNameExtensionFilter(langUtils.getString(XML_FILES_FILTER_KEY), "xml"))
                .build();
    }

    @Override
    public String getTitle() {
        return langUtils.getString(TITLE_KEY);
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public String getSideNavName() {
        return langUtils.getString(SIDE_NAV_KEY);
    }

    @Override
    public JPanel getContent() {
        JPanel content = new JPanel();
        content.setLayout(new GridBagLayout());
        GridBagConstraints c = initializeConstraints();
        c.gridwidth = 2;
        c.insets = FIELD_ROW_INSET;

        content.add(mainDescription, c);
        c.gridy++;

        content.add(versionsLabel, c);
        c.gridy++;

        content.add(mavenRepoLabel, c);
        c.gridy++;

        createRadioButtonsWithPath(content, c, publicMavenRepo, localMavenRepo, repoFileChooser);

        c.insets = FIELD_ROW_INSET;
        content.add(mavenSettingsLabel, c);
        c.gridy++;

        createRadioButtonsWithPath(content, c, defaultMavenSettings, alternativeMavenSettings, settingsFileChooser);
        c.gridy++;

        fillEmptySpace(content, c);

        return content;
    }

    private void createRadioButtonsWithPath(JPanel content, GridBagConstraints c, JRadioButton firstButton, JRadioButton secondButton, FileChooserPanel fileChooser) {
        c.insets = SUBSECTION_INSET;
        content.add(firstButton, c);
        c.gridy++;

        content.add(secondButton, c);
        c.gridy++;

        content.add(fileChooser, c);
        c.gridy++;

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(firstButton);
        buttonGroup.add(secondButton);

        secondButton.addItemListener(itemEvent -> {
            fileChooser.setEnabled(itemEvent.getStateChange() == ItemEvent.SELECTED);
        });
        fileChooser.setEnabled(secondButton.isSelected());
    }

    @Override
    public ValidationResult validate() {
        MavenSettingsPathValidator settingsPathValidator = new MavenSettingsPathValidator(langUtils);
        MavenRepositoryValidator repositoryValidator = new MavenRepositoryValidator(langUtils);

        final List<Supplier<ValidationResult>> validators = new ArrayList<>();
        if (localMavenRepo.isSelected()) {
            validators.add(()->repositoryValidator.validate(repoFileChooser.getText()));
        }
        if (defaultMavenSettings.isSelected()) {
            validators.add(()->settingsPathValidator.validate(Paths.get(DEFAULT_SETTINGS_PATH), false));
        } else {
            validators.add(()->settingsPathValidator.validate(settingsFileChooser.getText()));
        }
        ValidationResult currentResult = ValidationResult.ok();
        for (Supplier<ValidationResult> validator : validators) {
            final ValidationResult res = validator.get();
            if (res.getResult() == ValidationResult.Result.ERROR) {
                return res;
            } else if (currentResult.getResult() == ValidationResult.Result.OK) {
                currentResult = res;
            }
        }

        return currentResult;
    }

    @Override
    public void record(InstallationData installationData) {
        QuickstartsTask.Config config = installationData.getConfig(QuickstartsTask.Config.class);
        if (publicMavenRepo.isSelected()) {
            config.setQuickstartsRepository(DEFAULT_MAVEN_REPOSITORY);
        } else {
            config.setQuickstartsRepository(repoFileChooser.getText());

        }
        if (defaultMavenSettings.isSelected()) {
            config.setQuickstartsSettingsPath(DEFAULT_SETTINGS_PATH);
        } else {
            config.setQuickstartsSettingsPath(settingsFileChooser.getText());
        }
        installationData.addPostInstallTask(quickstartsTask);
        installationData.putConfig(config);
    }

    @Override
    public void rollback(InstallationData installationData) {
        installationData.removePostInstallTask(quickstartsTask);
    }
}
