/*
 *  Copyright 2021 Anyware Services
 *
 *  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.
 */

/**
 * This tool displays a list of threads
 */
Ext.define('Ametys.plugins.admin.jvmstatus.ThreadsTool', {
    extend: 'Ametys.tool.Tool',

    /**
     * @property {Ext.grid.Panel} _threadsGrid The threads grid
     * @private
     */

    getMBSelectionInteraction: function () 
    {
        return Ametys.tool.Tool.MB_TYPE_NOSELECTION;
    },

    createPanel: function () 
    {
        this._threadsGrid = this._drawThreadsPanel();
        return this._threadsGrid;
    },

    setParams: function (params)
    {
        this.callParent(arguments);
        this.refresh();
    },

    /**
     * Refreshes the tool
     */
    refresh: function ()
    {
        this.showRefreshing();
        this._threadsGrid.getStore().load({ callback: this.showRefreshed, scope: this });
    },

    /**
     * @private
     * Draw the panel displaying the caches
     */
    _drawThreadsPanel: function ()
    {
        var store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.admin.tool.ThreadsTool.Thread',
            proxy: {
                type: 'ametys',
                role: 'org.ametys.runtime.plugins.admin.jvmstatus.ThreadInfo',
                methodName: 'dumpAllThreads',
                methodArguments: [],
                reader: {
                	type: 'json'
                }
            },
            groupField: 'group',
            sorters: ['name']
        });

        return Ext.create('Ext.grid.Panel', {
            stateful: true,
            stateId: this.self.getName() + "$grid",
            store: store,
            plugins: ['gridfilters',
                      {
                        ptype: 'rowexpander',
                        id: 'rowexpander',
                        expandOnDblClick: false, // false to allow double click to select text
                        rowBodyTpl: new Ext.XTemplate('<div class="callstack">{stack-trace}</div>')
                      }],
        
            features: [{
                    ftype: 'grouping',
                    enableGroupingMenu: true
                } 
            ],
            viewConfig: {
                 enableTextSelection: true
            },
            
            columns: [
                { 
                    stateId: 'grid-name', header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_NAME}}", sortable: true, flex: 1, dataIndex: 'name-stack', filter: true,
                    renderer: function (value, metadata, record) {
                        return record.get("name");
                    }
                },
                { stateId: 'grid-group', header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_GROUP}}", sortable: true, flex: 1, hidden:true, dataIndex: 'group', filter: true},
                { 
                    stateId: 'grid-state', 
                    header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_STATE}}", 
                    sortable: true, 
                    width: 150, 
                    dataIndex: 'state', 
                    filter: {
                        type: 'list',
                        value: 'RUNNABLE'
                    }
                },
                { 
                    stateId: 'grid-stack-ametys', 
                    header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_STACK_AMETYS}}",
                    sortable: true, 
                    width: 75, 
                    dataIndex: 'stack-ametys', 
                    filter: {
                        type: 'boolean', 
                        value : true,
                        defaultValue: true
                    },
                    renderer: function (value) {
                        var isTrue = Ext.isBoolean(value) ? value : value == 'true';
                        if (isTrue)
                        {
                            return '<span class="a-grid-glyph ametysicon-check34" title="' + "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_STACK_AMETYS_YES}}" + '"></span>';
                        }
                        else
                        {
                            return "";
                        }
                    }
                },
                { stateId: 'grid-stack-size', header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_STACK_SIZE}}", sortable: true, width: 75, dataIndex: 'stack-size', filter: {value : {gt:0} }},
                { stateId: 'grid-lock-owner', header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_LOCK_OWNER}}", sortable: true, width: 200, dataIndex: 'lock-owner' },
                { 
                    stateId: 'grid-cpu', 
                    header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_CPU}}", 
                    sortable: true, 
                    hidden:true, 
                    width: 150,
                    dataIndex: 'cpu',
                    renderer: function(value) {
                        return "<div style='text-align: right'>" + Ext.util.Format.duration(value) + "<div>";
                    }
                },
                { 
                    stateId: 'grid-blocked-time', 
                    header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_BLOCKED_TIME}}", 
                    sortable: true, 
                    hidden:true, 
                    dataIndex: 'blocked-time',
                    width: 150,
                    renderer: function(value) {
                        return "<div style='text-align: right'>" + (value !== -1 ? Ext.util.Format.duration(value) : "-") + "<div>";
                    }
                },
                { 
                    stateId: 'grid-waited-time', 
                    header: "{{i18n PLUGINS_ADMIN_TOOL_THREADS_COL_WAITED_TIME}}", 
                    sortable: true, 
                    hidden:true, 
                    dataIndex: 'waited-time',
                    width: 150,
                    renderer: function(value) {
                        return "<div style='text-align: right'>" + (value !== -1 ? Ext.util.Format.duration(value) : "-") + "<div>";
                    }
                }
            ]
        })
    }
});

Ext.define('Ametys.plugins.admin.tool.ThreadsTool.Thread', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'name' },
        { name: 'group' },
        { name: 'state' },
        { name: 'cpu', type: 'number' },
        { name: 'blocked-time', type: 'number'},
        { name: 'waited-time', type: 'number'},
        { name: 'lock-owner' },
        { 
            name: 'stack-trace',
            convert: function (value, record) {
                if (value) {
                    return Ext.String.stacktraceJavaToHTML(value, "", "")
                }
                else {
                    return null;
                }
            }
        },
        {name: 'stack-ametys', type: 'boolean'},
        {name: 'stack-size', type: 'number'},
        {
            name: 'name-stack',
            calculate: function(data) {
                return data.name + " " + data["stack-trace"]
            } 
        }
    ]
});