{#
    (C) 2020-21 - ntop.org

    This is the template to generate the Manage Pool page.
#}
<div class="row">
    <div class="col-md-12 mb-4">
        <div class="card card-shadow">
            <div class="card-header">
                {# import the navbar inside the pool page to navigate through the pool tables #}
                {* template_utils.gen("pages/components/nav_tabs.template", menu) *}
            </div>
            <div class="card-body">
                    <table class="table table-bordered table-striped w-100" id="table-pools">
                        <thead>
                            <tr>
                                <th>{{ i18n("pools.name") }}</th>
                                {% if pool.is_all_pool then %}
                                <th>{{ i18n("pools.family") }}</th>
                                {% end %}
                                <th>{{ i18n("pools.members") }}</th>
                                <th>{{ i18n("actions") }}</th>
                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
            </div>
            <div class="card-footer">
                {* ui_utils.render_configuration_footer('pool', _GET["page"]) *}
            </div>
        </div>
    </div>
</div>

{# include the modal to add a new pool #}
{* template_utils.gen("pages/modals/pools/pool_modal.template", {
modal_type = "add",
pool = pool,
}) *}
{# include the modal to edit an existing pool #}
{* template_utils.gen("pages/modals/pools/pool_modal.template", {
modal_type = "edit",
pool = pool,
}) *}
{* template_utils.gen("pages/modals/pools/remove_pool.template", {
modal_type = "remove",
pool = pool
}) *}

{* template_utils.gen("pages/modals/factory-reset.template", {
    body = i18n("endpoint_notifications.factory_reset.body", { reset_element = i18n("pools.pools") }),
    title = i18n("endpoint_notifications.factory_reset.title", { reset_element = i18n("pools.pools") })
}) *}


<script type="text/javascript">

    let addCsrf = "{{ ntop.getRandomCSRFValue() }}";
    let editCsrf = "{{ ntop.getRandomCSRFValue() }}";
    let removeCsrf = "{{ ntop.getRandomCSRFValue() }}";

    const all_members = {* json.encode(pool.all_members) *};
    const endpoints = {* json.encode(pool.endpoints) *};
    const poolType = "{{ pool.name }}";

    const IS_ALL_POOL = {{ pool.is_all_pool }};
    const DEFAULT_POOL_ID = {{ (pool.instance.DEFAULT_POOL_ID or 0) }};
    const IS_NEDGE = {{ is_nedge or false }};

    Object.freeze(all_members);
    Object.freeze(endpoints);

    i18n_ext.warning = "{{ i18n('warning', {}) }}";
    i18n_ext.showing_x_to_y_rows = "{{ i18n('showing_x_to_y_rows', {x='_START_', y='_END_', tot='_TOTAL_'}) }}";
    i18n_ext.search = "{{ i18n('search') }}";
    i18n_ext.delete = "{{ i18n('delete') }}";
    i18n_ext.edit = "{{ i18n('edit') }}";
    i18n_ext.all = "{{ i18n('all') }}";
    i18n_ext.used_by = "{{ i18n('used_by') }}";
    i18n_ext.others = "{{ i18n('others') }}";
    i18n_ext.other = "{{ i18n('other') }}";
    i18n_ext.and = "{{ i18n('and') }}";
    i18n_ext.manage = "{{ i18n('host_pools.manage_pool') }}"
    i18n_ext.unbounded_members = "{{ i18n('pools.unbounded_members') }}";

    i18n_ext.poolFamilies = {* json.encode(pool.pool_families) *};

    i18n_ext.rest = {
        INVALID_HOST: "{{ i18n('rest_consts.INVALID_HOST') }}",
        INVALID_ARGUMENTS: "{{ i18n('rest_consts.INVALID_ARGUMENTS') }}",
        NOT_GRANTED: "{{ i18n('rest_consts.NOT_GRANTED') }}",
        ADD_POOL_FAILED: "{{ i18n('rest_consts.ADD_POOL_FAILED') }}",
        EDIT_POOL_FAILED: "{{ i18n('rest_consts.EDIT_POOL_FAILED') }}",
        DELETE_POOL_FAILED: "{{ i18n('rest_consts.DELETE_POOL_FAILED') }}",
    };
    
    
    const MAX_RECIPIENTS_TO_SHOW = 10;

    const renableDisabledOptions = (selector, members) => {
        members.forEach(m => {

            if (!all_members || !all_members[m]) return m;
            // if the member name is not defined the use the member's key
            const name = all_members[m].name || m;

            $(`${selector} option[value='${m}']`)
                .removeAttr("disabled").removeAttr("data-pool-id").text(name);
        });
        $(`${selector}`).selectpicker('refresh');
    }

    const markUsedOptions = (selector, members, poolName, poolId) => {
        members.forEach(m => {
            $(`${selector} option[value='${m}']`)
                .attr("disabled", "disabled")
                .attr("data-pool-id", poolId)
                .text(`${all_members[m].name || m} (${poolName})`);
        });
        $(`${selector}`).selectpicker('refresh');
    }

    const makeDataTableColumns = () => {

        const columns = [
            {
                data: 'name',
                width: "10%",
                render: function(name, type, pool) {

                    if (type == "display" && pool.pool_id == DEFAULT_POOL_ID) {
                        return `<i>${name}</i>`;
                    }

                    return name;
                }
            },
            {
                data: null,
                orderable: false,
                width: "40%",
                render: function(data, type, row) {

                    /* if it's the default pool then show an unbounded members message */
                    if (type == "display" && row.pool_id == DEFAULT_POOL_ID) return i18n_ext.unbounded_members;

                    if (type == "display" && row.members.length == 0) return "";
                    // show only the first 10 members, append some dots
                    // if the members are more than 10
                    const memberNames = row.members.map((memberId) => {

                        const member = row.member_details[memberId];
                        if (member.name == undefined && member.hostkey == undefined) return memberId;
                        if (!all_members || !all_members[memberId]) {
                            return member.hostkey || member.name;
                        }

                        if (all_members[memberId].name == undefined) return memberId;
                        return all_members[memberId].name;
                    });

                    if (type == "display") {
                        return NtopUtils.arrayToListString(memberNames, MAX_RECIPIENTS_TO_SHOW);
                    }
                }
            },
            {
                data: null, targets: -1, className: 'text-center',
                width: "10%",
                render: function(_, type, pool) {
                    let changable_pool = true;

                    for(const pool_names of unchangable_pool_names) {
                        if(pool_names === pool.name) {
                            changable_pool = false;
                            break;
                        }
                    }

                    /* disable actions for ALL_POOL page */
                    if (IS_ALL_POOL) return;

                    const buttons = [
                        { class: 'btn-info', icon: 'fa-edit', modal: '#edit-pool', title: `${i18n_ext.edit}` },
                        { class: `btn-danger ${((pool.pool_id == DEFAULT_POOL_ID || IS_NEDGE) || !changable_pool) ? 'disabled' : '' }`, icon: 'fa-trash', modal: '#remove-pool', title: `${i18n_ext.delete}`}
                    ];

                    if (poolType == "host") {
                        buttons.unshift(
                            {
                                class: `btn-info ${(pool.pool_id == DEFAULT_POOL_ID) ? 'disabled' : '' }`,
                                icon: 'fa-layer-group',
                                href: `${http_prefix}/lua/admin/manage_host_members.lua?pool=${pool.pool_id}`,
                                title: `${i18n_ext.manage}`
                            }
                        );
                    }

                    return DataTableUtils.createActionButtons(buttons);
                }
            }
        ];

        // if the ALL_POOL page is selected then show the pool family
        if (IS_ALL_POOL) {
            columns.splice(1, 0, {
                data: 'key',
                render: (key, type, pool) => {
                    if (type == "display") return i18n_ext.poolFamilies[key];
                    return key;
                }
            });
        }

        return columns;
    }

    let dtConfig = DataTableUtils.getStdDatatableConfig( [
        {
            text: '<i class="fas fa-plus"></i>',
            enabled: !IS_ALL_POOL && !IS_NEDGE,
            action: () => { $(`#add-pool`).modal('show'); }
        },
        {
            text: '<i class="fas fa-sync"></i>',
            enabled: !IS_ALL_POOL,
            action: function(e, dt, node, config) {
                $poolTable.ajax.reload();
            }
        }
    ]);

    dtConfig = DataTableUtils.setAjaxConfig(dtConfig, endpoints.get_all_pools, 'rsp');
    dtConfig = DataTableUtils.extendConfig(dtConfig, {
        stateSave: true,
        columns: makeDataTableColumns(),
        initComplete: function(settings, json) {

            const tableAPI = settings.oInstance.api();
            // when the data has been fetched check if the url has a pool params
            DataTableUtils.openEditModalByQuery({
                paramName: 'pool_id',
                datatableInstance: tableAPI,
                modalHandler: $editModalHandler,
            });
        }
    });

    const $poolTable = $(`#table-pools`).DataTable(dtConfig);
    DataTableUtils.addToggleColumnsDropdown($poolTable);

    $(`#add-pool form`).modalHandler({
        method: 'post',
        csrf: addCsrf,
        resetAfterSubmit: false,
        endpoint: endpoints.add_pool,
        beforeSumbit: function() {
            const members = $(`#add-pool form select[name='members']`).val() || [];

            $(`#add-modal-feedback`).hide();

            return {
                pool_name: $(`#add-pool form input[name='name']`).val().trim(),
                pool_members: members.join(',')
            };
        },
        onSubmitSuccess: function (response, textStatus, modalHandler) {
            if (response.rc < 0) {
                $(`#add-modal-feedback`).html(response.rc_str_hr).fadeIn();
                return;
            }

            const poolName = $(`#add-pool form input[name='name']`).val().trim();

            if (poolType != "host") {
                // get the new members array
                const members = $(`#add-pool form select[name='members']`).val();
                // mark select entries with the new pool created
                markUsedOptions(`#add-pool form select[name='members']`, members, poolName, response.rsp.pool_id);
                markUsedOptions(`#edit-pool form select[name='members']`, members, poolName, response.rsp.pool_id);
            }

            $poolTable.ajax.reload();
            $(`#add-pool`).modal('hide');
        }
    }).invokeModalInit();

    const $editModalHandler = $(`#edit-pool form`).modalHandler({
        method: 'post',
        csrf: editCsrf,
        endpoint: endpoints.edit_pool,
        resetAfterSubmit: false,
        onModalInit: (pool) => {

            let changable_pool = true;

            for(const pool_names of unchangable_pool_names) {
                if(pool_names === pool.name) {
                    changable_pool = false;
                    break;
                }
            }
            
            // disable pool name field if we are editing the default pool
            // also hide the members multiselect
            if (pool.pool_id == DEFAULT_POOL_ID || !changable_pool) {
                $(`#edit-pool form input[name='name']`).attr("readonly", "true");
                $(`#edit-pool .members-container`).hide();
            }
            else {
                $(`#edit-pool form input[name='name']`).removeAttr("readonly");
                $(`#edit-pool .members-container`).show();
            }

            // disable all the options whose have a data-pool-id attribute
            $(`#edit-pool form select[name='members'] option[data-pool-id]`).attr("disabled", "disabled");

            // enable only the option used by the pool
            $(`#edit-pool form select[name='members'] option`).each(function() {

                const id = $(this).val();
                // if the id belong to the pool then remove the disabled attribute
                if (pool.members.indexOf(id) > -1) {
                    $(this).removeAttr("disabled");
                }
            });

            $(`#edit-pool-name-input`).off('keyup').on('keyup', function() {
                const name = $(this).val()
                $(`[data-pool-id='${pool.pool_id}']`).each(function() {
                    const m = $(this).val();
                    $(this).text(`${all_members[m].name || m} (${name})`);
                });
            });

            // load the modal with the pool data
            $(`#edit-pool form input[name='name']`).val(pool.name);
            $(`#edit-pool form select[name='members']`).val(pool.members);
            $(`#edit-pool form select[name='members']`).selectpicker('refresh');

            if (poolType == "host") {
                const href = $(`#edit-link`).attr('href').replace(/pool\=[0-9]+/, `pool=${pool.pool_id}`);
                $(`#edit-link`).attr('href', href);
            }
        },
        beforeSumbit: (pool) => {

            const members = $(`#edit-pool form select[name='members']`).val() || [];

            const data = {
                pool: pool.pool_id,
                pool_name: $(`#edit-pool form input[name='name']`).val().trim()
            };

            if (poolType != "host") {
                data.pool_members = members.join(',');
            }
            else {
                data.pool_members = pool.members.join(',');
            }

            return data;
        },
        onSubmitSuccess:  (response, dataSent, modalHandler) => {

            const oldPoolData = modalHandler.data;

            if (response.rc < 0) {
                $(`#edit-modal-feedback`).html(response.rc_str_hr).fadeIn();
                return;
            }

            const newPoolName = $(`#edit-pool form input[name='name']`).val();
            // update the pool name inside the selects if changed
            if (newPoolName != oldPoolData.name) {
                $(`option[data-pool-id='${oldPoolData.pool_id}']`).each(function() {
                    const value = $(this).val();
                    if (poolType != "host")
                        $(this).text(`${all_members[value].name || value} (${i18n_ext.used_by} ${newPoolName})`)
                });
            }

            // the host pool modals don't have any members
            if (poolType != "host" && oldPoolData.pool_id != DEFAULT_POOL_ID) {
                // get the newMembers and the oldMembers and create two subset of them
                const oldMembers = oldPoolData.members;
                const newMembers = $(`#edit-pool form select[name='members']`).val();
                // this subset contains the removed members from the pool
                const oldToRenable = oldMembers.filter((m1) => !newMembers.find(m2 => m1 == m2));
                // this subset contains the new members added to the pool
                const newToMark = newMembers.filter((m1) => !oldMembers.find(m2 => m1 == m2));

                renableDisabledOptions(`#add-pool form select[name='members']`, oldToRenable);
                renableDisabledOptions(`#edit-pool form select[name='members']`, oldToRenable);

                markUsedOptions(`#add-pool form select[name='members']`, newToMark, newPoolName, oldPoolData.pool_id);
                markUsedOptions(`#edit-pool form select[name='members']`, newToMark, newPoolName, oldPoolData.pool_id);
            }

            // clean the form and reload the table
            $poolTable.ajax.reload();
            $(`#edit-pool`).modal('hide');
        }
    });

    const $removeModalHandler = $(`#remove-pool form`).modalHandler({
        method: 'post',
        csrf: removeCsrf,
        endpoint: endpoints.delete_pool,
        resetAfterSubmit: false,
        onModalInit: (pool) => {
            $(`#remove-pool form button[type='submit']`).removeAttr("disabled");
            $(`.delete-pool-name`).text(pool.name);
        },
        beforeSumbit: (pool) => {
            return { pool: pool.pool_id };
        },
        onSubmitSuccess: (response, textStatus, modalHandler) => {

            const oldPoolData = modalHandler.data;

            if (response.rc < 0) {
                $(`#remove-modal-feedback`).html(response.rc_str_hr).fadeIn();
                return;
            }

            // renable the members removed from the pool inside the modal
            renableDisabledOptions(`#add-pool form select[name='members']`, oldPoolData.members);
            renableDisabledOptions(`#edit-pool form select[name='members']`, oldPoolData.members);

            $poolTable.ajax.reload();
            $(`#remove-pool`).modal('hide');
        }
    });

    $(`#table-pools`).on('click', `a[href='#edit-pool']`, function (e) {
        const selectedPool = $poolTable.row($(this).parent().parent().parent().parent()).data();
        $editModalHandler.invokeModalInit(selectedPool);
        $(`#edit-pool`).modal('show')
    });

    $(`#table-pools`).on('click', `a[href='#remove-pool']`, function (e) {
        const selectedPool = $poolTable.row($(this).parent().parent().parent().parent()).data();
        $removeModalHandler.invokeModalInit(selectedPool);
        $(`#remove-pool`).modal('show')
    });

</script>
