package org.jboss.installer.screens.jsf;

import org.jboss.installer.common.FileChooserPanel;
import org.jboss.installer.common.UiResources;
import org.jboss.installer.core.FileUtils;
import org.jboss.installer.core.LanguageUtils;
import org.jboss.installer.core.MnemonicUtils;
import org.jboss.installer.core.ValidationResult;
import org.jboss.installer.postinstall.task.JsfLibraryTask;
import org.jboss.installer.validators.CombiningValidator;
import org.jboss.installer.validators.JsfUtils;
import org.jboss.installer.validators.MavenRepositoryValidator;
import org.jboss.installer.validators.RepositoryContentValidator;
import org.jboss.installer.validators.WritableFolderValidator;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.nio.file.Path;

import static javax.swing.JFileChooser.DIRECTORIES_ONLY;
import static org.jboss.installer.postinstall.task.jsf.MyFacesJsfLibrarySetup.MYFACES_API_ARTIFACT_ID;
import static org.jboss.installer.postinstall.task.jsf.MyFacesJsfLibrarySetup.MYFACES_GROUP_ID;
import static org.jboss.installer.postinstall.task.jsf.MyFacesJsfLibrarySetup.MYFACES_IMPL_ARTIFACT_ID;
import static org.jboss.installer.screens.DefaultScreen.DESCRIPTION_INSET;
import static org.jboss.installer.screens.JSFInstallScreen.JSF_VERSION_KEY;
import static org.jboss.installer.validators.CertificateSecurityDomainValidator.GENERIC_VALIDATION_EMPTY_FIELD;
import static org.jboss.installer.validators.JsfValidator.JSF_VERSION_NOT_SUPPORTED_KEY;

class CreateNewChannelPanel extends JPanel {
    public static final String MYFACES_REPOSITORY_LABEL_KEY = "jsf_install.myfaces_repository.label";
    public static final String CHANNEL_REPOSITORY_LABEL_KEY = "jsf_install.channel_repository.label";
    private final FileChooserPanel sourceRepositoryChooser;
    private final FileChooserPanel targetRepositoryChooser;
    private final JTextField jsfVersionField;
    private final LanguageUtils langUtils;

    public CreateNewChannelPanel(LanguageUtils langUtils, MnemonicUtils mnemonicUtils, Path installationDir) {
        super(new GridBagLayout());

        this.langUtils = langUtils;

        this.sourceRepositoryChooser = FileChooserPanel.builder(langUtils, DIRECTORIES_ONLY, mnemonicUtils)
                .baseFolder("https://repo1.maven.org/maven2/")
                .build();
        this.targetRepositoryChooser = FileChooserPanel.builder(langUtils, DIRECTORIES_ONLY, mnemonicUtils)
                .baseFolder(installationDir.resolve("jsf-repo").toString())
                .build();
        this.jsfVersionField = UiResources.createTextField("");

        final GridBagConstraints c = UiResources.initializeConstraints();
        c.gridwidth = 3;
        c.weightx = 1;

        c.insets = DESCRIPTION_INSET;
        this.add(UiResources.createFieldLabel(langUtils.getString("jsf_install.create_channel.desc",
                MYFACES_GROUP_ID, MYFACES_API_ARTIFACT_ID, MYFACES_GROUP_ID, MYFACES_IMPL_ARTIFACT_ID)), c);

        c.gridy++;
        c.gridx = 0;
        c.gridwidth = 1;
        final JLabel jsfVersionLabel = UiResources.createFieldLabel(langUtils.getString(JSF_VERSION_KEY) + ":");
        this.add(jsfVersionLabel, c);
        jsfVersionLabel.setToolTipText(langUtils.getString(JSF_VERSION_KEY + ".tooltip"));

        c.gridx = 1;
        c.gridwidth = 2;
        this.add(jsfVersionField, c);
        jsfVersionLabel.setToolTipText(langUtils.getString(JSF_VERSION_KEY + ".tooltip"));

        c.gridx = 0;
        c.gridwidth = 3;
        c.gridy++;
        final JLabel jsfRepositoryLabel = UiResources.createFieldLabel(langUtils.getString(MYFACES_REPOSITORY_LABEL_KEY));
        this.add(jsfRepositoryLabel, c);
        jsfVersionLabel.setToolTipText(langUtils.getString(MYFACES_REPOSITORY_LABEL_KEY + ".tooltip"));

        c.gridy++;
        c.gridwidth = 3;
        this.add(sourceRepositoryChooser, c);
        jsfVersionLabel.setToolTipText(langUtils.getString(MYFACES_REPOSITORY_LABEL_KEY + ".tooltip"));

        c.gridx = 0;
        c.gridwidth = 3;
        c.gridy++;
        final JLabel channelTargetPathLabel = UiResources.createFieldLabel(langUtils.getString(CHANNEL_REPOSITORY_LABEL_KEY));
        this.add(channelTargetPathLabel, c);
        channelTargetPathLabel.setToolTipText(langUtils.getString(CHANNEL_REPOSITORY_LABEL_KEY + ".tooltip"));

        c.gridy++;
        c.gridwidth = 3;
        this.add(targetRepositoryChooser, c);
        channelTargetPathLabel.setToolTipText(langUtils.getString(CHANNEL_REPOSITORY_LABEL_KEY + ".tooltip"));
    }

    protected String getSourceRepositoryValue() {
        return UiResources.readTextValue(sourceRepositoryChooser);
    }

    protected String getJsfVersion() {
        return UiResources.readTextValue(jsfVersionField);
    }

    protected String getTargetChannelPath() {
        return UiResources.readTextValue(targetRepositoryChooser);
    }

    protected void populateConfig(JsfLibraryTask.Config config) {
        config.setJsfVersion(getJsfVersion());

        config.setJsfProject(JsfLibraryTask.Config.JsfProject.MyFaces);

        config.setLocalChannelRepositoryPath(getTargetChannelPath());

        config.setRemoteMavenRepositoryUrl(FileUtils.asUrl(getSourceRepositoryValue()));
    }

    public ValidationResult validateInput() {
        final String jsfVersion = getJsfVersion();
        final String sourceRepositoryValue = getSourceRepositoryValue();
        final String targetChannelPath = getTargetChannelPath();

        if (jsfVersion == null || jsfVersion.trim().isEmpty()) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD,
                    langUtils.getString(JSF_VERSION_KEY)));
        }
        if (sourceRepositoryValue == null || sourceRepositoryValue.trim().isEmpty()) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD,
                    langUtils.getString(MYFACES_REPOSITORY_LABEL_KEY)));
        }
        if (targetChannelPath == null || targetChannelPath.trim().isEmpty()) {
            return ValidationResult.error(langUtils.getString(GENERIC_VALIDATION_EMPTY_FIELD,
                    langUtils.getString(CHANNEL_REPOSITORY_LABEL_KEY)));
        }

        final JsfUtils jsfUtils = new JsfUtils();
        final String cleanedVer = jsfUtils.cleanedVer(jsfVersion);
        if (cleanedVer == null || cleanedVer.isEmpty()) {
            return ValidationResult.error(langUtils.getString(JSF_VERSION_NOT_SUPPORTED_KEY, jsfVersion));
        }

        final RepositoryContentValidator validator = new RepositoryContentValidator(langUtils);
        return CombiningValidator.of(()->new MavenRepositoryValidator(langUtils).validate(sourceRepositoryValue),
                ()->new WritableFolderValidator("jsf_install", langUtils).validate(targetChannelPath, false),
                ()-> validator.validate(FileUtils.asUrl(sourceRepositoryValue), MYFACES_GROUP_ID, MYFACES_API_ARTIFACT_ID, jsfVersion),
                ()-> validator.validate(FileUtils.asUrl(sourceRepositoryValue), MYFACES_GROUP_ID, MYFACES_IMPL_ARTIFACT_ID, jsfVersion))
                .validate();
    }
}
