/*
 * 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.apache.syncope.client.console.notifications;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.events.EventCategoryPanel;
import org.apache.syncope.client.console.panels.search.AbstractSearchPanel;
import org.apache.syncope.client.console.panels.search.AnyObjectSearchPanel;
import org.apache.syncope.client.console.panels.search.GroupSearchPanel;
import org.apache.syncope.client.console.panels.search.SearchClause;
import org.apache.syncope.client.console.panels.search.UserSearchPanel;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.ImplementationRestClient;
import org.apache.syncope.client.console.rest.AuditRestClient;
import org.apache.syncope.client.console.rest.NotificationRestClient;
import org.apache.syncope.client.console.rest.SchemaRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.MultiPanel;
import org.apache.syncope.client.console.wizards.BaseAjaxWizardBuilder;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.DerSchemaTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.NotificationTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
import org.apache.syncope.common.lib.to.VirSchemaTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.IdRepoImplementationType;
import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.wizard.WizardModel;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.util.ListModel;
import org.apache.wicket.validation.validator.EmailAddressValidator;

public class NotificationWizardBuilder extends BaseAjaxWizardBuilder<NotificationWrapper> {

    private static final long serialVersionUID = -1975312550059578553L;

    private final NotificationRestClient restClient = new NotificationRestClient();

    /**
     * Construct.
     *
     * @param notificationTO notification.
     * @param pageRef Caller page reference.
     */
    public NotificationWizardBuilder(final NotificationTO notificationTO, final PageReference pageRef) {
        super(new NotificationWrapper(notificationTO), pageRef);
    }

    @Override
    protected Serializable onApplyInternal(final NotificationWrapper modelObject) {
        modelObject.fillRecipientConditions();
        modelObject.fillAboutConditions();

        final boolean createFlag = modelObject.getInnerObject().getKey() == null;
        if (createFlag) {
            NotificationRestClient.create(modelObject.getInnerObject());
        } else {
            NotificationRestClient.update(modelObject.getInnerObject());
        }

        return null;
    }

    @Override
    protected WizardModel buildModelSteps(final NotificationWrapper modelObject, final WizardModel wizardModel) {
        wizardModel.add(new Details(modelObject));
        wizardModel.add(new Recipients(modelObject));
        wizardModel.add(new Events(modelObject));
        wizardModel.add(new Abouts(modelObject));
        return wizardModel;
    }

    public class Details extends WizardStep {

        private static final long serialVersionUID = -7709805590497687958L;

        public Details(final NotificationWrapper modelObject) {
            NotificationTO notificationTO = modelObject.getInnerObject();
            boolean createFlag = notificationTO.getKey() == null;

            AjaxTextFieldPanel sender = new AjaxTextFieldPanel("sender", getString("sender"),
                    new PropertyModel<>(notificationTO, "sender"));
            sender.addRequiredLabel();
            sender.addValidator(EmailAddressValidator.getInstance());
            add(sender);

            AjaxTextFieldPanel subject = new AjaxTextFieldPanel("subject", getString("subject"),
                    new PropertyModel<>(notificationTO, "subject"));
            subject.addRequiredLabel();
            add(subject);

            AjaxDropDownChoicePanel<String> template = new AjaxDropDownChoicePanel<>(
                    "template", getString("template"),
                    new PropertyModel<>(notificationTO, "template"));
            template.setChoices(restClient.listTemplates().stream().
                    map(EntityTO::getKey).collect(Collectors.toList()));

            template.addRequiredLabel();
            add(template);

            AjaxDropDownChoicePanel<TraceLevel> traceLevel = new AjaxDropDownChoicePanel<>(
                    "traceLevel", getString("traceLevel"),
                    new PropertyModel<>(notificationTO, "traceLevel"));
            traceLevel.setChoices(List.of(TraceLevel.values()));
            traceLevel.addRequiredLabel();
            add(traceLevel);

            final AjaxCheckBoxPanel isActive = new AjaxCheckBoxPanel("isActive",
                    getString("isActive"), new PropertyModel<>(notificationTO, "active"));
            if (createFlag) {
                isActive.getField().setDefaultModelObject(Boolean.TRUE);
            }
            add(isActive);
        }

    }

    public static class Events extends WizardStep {

        private static final long serialVersionUID = -7709805590497687958L;

        public Events(final NotificationWrapper modelObject) {
            setTitleModel(new ResourceModel("events"));

            add(new EventCategoryPanel(
                    "eventSelection",
                    AuditRestClient.listEvents(),
                    new PropertyModel<List<String>>(modelObject.getInnerObject(), "events")) {

                private static final long serialVersionUID = 6429053774964787735L;

                @Override
                protected List<String> getListAuthRoles() {
                    return List.of();
                }

                @Override
                protected List<String> getChangeAuthRoles() {
                    return List.of();
                }
            });
        }
    }

    public static class About extends Panel {

        private static final long serialVersionUID = -9149543787708482882L;

        public About(final String id, final IModel<Pair<String, List<SearchClause>>> model) {
            super(id, model);
            setOutputMarkupId(true);

            AjaxDropDownChoicePanel<String> type =
                    new AjaxDropDownChoicePanel<>("about", "anyType", new Model<String>() {

                        private static final long serialVersionUID = -2350296434572623272L;

                        @Override
                        public String getObject() {
                            return model.getObject().getLeft();
                        }

                        @Override
                        public void setObject(final String object) {
                            model.setObject(Pair.of(object, model.getObject().getRight()));
                        }

                    });
            type.setChoices(AnyTypeRestClient.list());
            type.addRequiredLabel();
            add(type);

            ListModel<SearchClause> clauseModel = new ListModel<SearchClause>() {

                private static final long serialVersionUID = 3769540249683319782L;

                @Override
                public List<SearchClause> getObject() {
                    return model.getObject().getRight();
                }

                @Override
                public void setObject(final List<SearchClause> object) {
                    model.getObject().setValue(object);
                }
            };

            WebMarkupContainer searchContainer = new WebMarkupContainer("search");
            add(searchContainer.setOutputMarkupId(true));

            searchContainer.add(getClauseBuilder(model.getObject().getLeft(), clauseModel).build("clauses"));

            type.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {

                private static final long serialVersionUID = -1107858522700306810L;

                @Override
                protected void onUpdate(final AjaxRequestTarget target) {
                    clauseModel.getObject().clear();
                    searchContainer.addOrReplace(getClauseBuilder(type.getModelObject(), clauseModel).
                            build("clauses").setRenderBodyOnly(true));
                    target.add(searchContainer);
                }
            });
        }

        private AbstractSearchPanel.Builder<?> getClauseBuilder(
                final String type, final ListModel<SearchClause> clauseModel) {

            AbstractSearchPanel.Builder<?> clause;

            switch (type) {
                case "USER":
                    clause = new UserSearchPanel.Builder(clauseModel);
                    break;

                case "GROUP":
                    clause = new GroupSearchPanel.Builder(clauseModel);
                    break;

                default:
                    clause = new AnyObjectSearchPanel.Builder(type, clauseModel);
            }

            return clause;
        }
    }

    public class Abouts extends WizardStep {

        private static final long serialVersionUID = -7709805590497687958L;

        public Abouts(final NotificationWrapper modelObject) {
            setTitleModel(new ResourceModel("about"));

            WebMarkupContainer aboutContainer = new WebMarkupContainer("about");
            aboutContainer.setOutputMarkupId(true);
            add(aboutContainer);

            IModel<List<Pair<String, List<SearchClause>>>> model = new PropertyModel<>(modelObject, "aboutClauses");

            aboutContainer.add(new MultiPanel<Pair<String, List<SearchClause>>>("abouts", "abouts", model) {

                private static final long serialVersionUID = -2481579077338205547L;

                @Override
                protected Pair<String, List<SearchClause>> newModelObject() {
                    return Pair.<String, List<SearchClause>>of(AnyTypeKind.USER.name(), new ArrayList<>());
                }

                @Override
                protected About getItemPanel(final ListItem<Pair<String, List<SearchClause>>> item) {

                    return new About("panel", new Model<Pair<String, List<SearchClause>>>() {

                        private static final long serialVersionUID = 6799404673615637845L;

                        @Override
                        public Pair<String, List<SearchClause>> getObject() {
                            return item.getModelObject();
                        }

                        @Override
                        public void setObject(final Pair<String, List<SearchClause>> object) {
                            item.setModelObject(object);
                        }

                        @Override
                        public void detach() {
                            // no detach
                        }
                    });
                }

                @Override
                protected void sendError(final String message) {
                    SyncopeConsoleSession.get().error(getString(Constants.OPERATION_ERROR));
                }
            }.hideLabel());
        }
    }

    public static class Recipients extends WizardStep {

        private static final long serialVersionUID = -7709805590497687958L;

        private final IModel<List<String>> recipientProviders = new LoadableDetachableModel<List<String>>() {

            private static final long serialVersionUID = 5275935387613157447L;

            @Override
            protected List<String> load() {
                return ImplementationRestClient.list(IdRepoImplementationType.RECIPIENTS_PROVIDER).stream().
                        map(EntityTO::getKey).sorted().collect(Collectors.toList());
            }
        };

        public Recipients(final NotificationWrapper modelObject) {
            setTitleModel(new ResourceModel("recipients"));

            NotificationTO notificationTO = modelObject.getInnerObject();

            AjaxTextFieldPanel recipientAttrName = new AjaxTextFieldPanel(
                    "recipientAttrName", new ResourceModel("recipientAttrName", "recipientAttrName").getObject(),
                    new PropertyModel<>(notificationTO, "recipientAttrName"));
            recipientAttrName.setChoices(getSchemas());
            recipientAttrName.addRequiredLabel();
            recipientAttrName.setTitle(getString("intAttrNameInfo.help")
                    + "<code>groups[groupName].attribute</code>, "
                    + "<code>users[userName].attribute</code>, "
                    + "<code>anyObjects[anyObjectName].attribute</code>, "
                    + "<code>relationships[relationshipType][anyType].attribute</code> or "
                    + "<code>memberships[groupName].attribute</code> or "
                    + "<code>privileges[applicationKey]</code>", true);
            add(recipientAttrName);

            AjaxTextFieldPanel staticRecipientsFieldPanel =
                    new AjaxTextFieldPanel("panel", "staticRecipients", new Model<>());
            staticRecipientsFieldPanel.addValidator(EmailAddressValidator.getInstance());
            add(new MultiFieldPanel.Builder<>(
                    new PropertyModel<List<String>>(notificationTO, "staticRecipients")).
                    build("staticRecipients", "staticRecipients", staticRecipientsFieldPanel).hideLabel());

            add(new UserSearchPanel.Builder(
                    new PropertyModel<>(modelObject, "recipientClauses")).
                    required(false).build("recipients"));

            AjaxDropDownChoicePanel<String> recipientsProvider = new AjaxDropDownChoicePanel<>(
                    "recipientsProvider", "recipientsProvider",
                    new PropertyModel<>(notificationTO, "recipientsProvider"), false);
            recipientsProvider.setChoices(recipientProviders.getObject());
            add(recipientsProvider);

            AjaxCheckBoxPanel selfAsRecipient = new AjaxCheckBoxPanel("selfAsRecipient",
                    getString("selfAsRecipient"), new PropertyModel<>(notificationTO, "selfAsRecipient"));
            if (notificationTO.getKey() == null) {
                selfAsRecipient.getField().setDefaultModelObject(Boolean.FALSE);
            }
            add(selfAsRecipient);
        }
    }

    private static List<String> getSchemas() {
        AnyTypeTO type = null;
        try {
            type = AnyTypeRestClient.read(AnyTypeKind.USER.name());
        } catch (SyncopeClientException e) {
            LOG.error("While reading all any types", e);
        }

        String[] anyTypeClasses = Optional.ofNullable(type)
                .map(anyTypeTO -> anyTypeTO.getClasses().toArray(new String[] {})).orElseGet(() -> new String[0]);

        List<String> result = new ArrayList<>();
        result.add(Constants.USERNAME_FIELD_NAME);

        result.addAll(SchemaRestClient.<PlainSchemaTO>getSchemas(SchemaType.PLAIN, null, anyTypeClasses).
                stream().map(EntityTO::getKey).collect(Collectors.toList()));
        result.addAll(SchemaRestClient.<DerSchemaTO>getSchemas(SchemaType.DERIVED, null, anyTypeClasses).
                stream().map(EntityTO::getKey).collect(Collectors.toList()));
        result.addAll(SchemaRestClient.<VirSchemaTO>getSchemas(SchemaType.VIRTUAL, null, anyTypeClasses).
                stream().map(EntityTO::getKey).collect(Collectors.toList()));

        Collections.sort(result);
        return result;
    }
}
