function timeAndFrom(field, fromNow, emptyText) {
    if (!emptyText) {
        emptyText = '未停止'
    }
    // language=TEXT
    return "<span class='font-bold'>${" + fromNow + "}</span><br> ${IF(" + field + " === 0, '(" + emptyText + ")', CONCATENATE('(',DATETOSTR(DATE(" + field + ")),')'))}"
}

function yarnCrudColumns() {
    return [
        {
            name: 'id',
            label: 'ID',
            width: 240,
            fixed: 'left',
            ...copyField('id')
        },
        {
            name: 'name',
            label: '名称',
            fixed: 'left',
            ...copyField('name')
        },
        {
            label: '用户',
            width: 80,
            type: 'tooltip-wrapper',
            body: '${TRUNCATE(user, 8)}',
            content: '${user}',
        },
        {
            name: 'startedTime',
            label: '启动时间',
            width: 140,
            type: 'tpl',
            tpl: timeAndFrom('startedTime', 'startTimeFromNow'),
            sortable: true,
            align: 'center',
            canAccessSuperData: false,
        },
        {
            name: 'finishedTime',
            label: '停止时间',
            width: 140,
            type: 'tpl',
            tpl: timeAndFrom('finishedTime', 'finishTimeFromNow'),
            sortable: true,
            align: 'center',
            canAccessSuperData: false,
        },
        {
            name: 'state',
            label: '运行状态',
            width: 70,
            align: 'center',
            type: 'mapping',
            canAccessSuperData: false,
            map: {
                'NEW': '<span class=\'label bg-pink-300\'>创建中</span>',
                'NEW_SAVING': '<span class=\'label bg-purple-300\'>已创建</span>',
                'SUBMITTED': '<span class=\'label bg-indigo-300\'>已提交</span>',
                'ACCEPTED': '<span class=\'label bg-cyan-300\'>调度中</span>',
                'RUNNING': '<span class=\'label label-success\'>运行中</span>',
                'FINISHED': '<span class=\'label label-default\'>已结束</span>',
                'FAILED': '<span class=\'label label-danger\'>已失败</span>',
                'KILLED': '<span class=\'label label-warning\'>被停止</span>',
                '*': '<span class=\'label bg-gray-300\'>${state}</span>'
            },
            filterable: {
                multiple: true,
                options: [
                    {label: '创建中', value: 'NEW'},
                    {label: '已创建', value: 'NEW_SAVING'},
                    {label: '已提交', value: 'SUBMITTED'},
                    {label: '调度中', value: 'ACCEPTED'},
                    {label: '运行中', value: 'RUNNING'},
                    {label: '已结束', value: 'FINISHED'},
                    {label: '已失败', value: 'FAILED'},
                    {label: '被停止', value: 'KILLED'},
                ]
            }
        }, {
            name: 'finalStatus',
            label: '最终状态',
            width: 70,
            align: 'center',
            type: 'mapping',
            canAccessSuperData: false,
            map: {
                'UNDEFINED': '<span class=\'label label-info\'>运行</span>',
                'SUCCEEDED': '<span class=\'label label-success\'>成功</span>',
                'FAILED': '<span class=\'label label-danger\'>失败</span>',
                'KILLED': '<span class=\'label label-warning\'>终止</span>',
                'ENDED': '<span class=\'label label-default\'>结束</span>',
                '*': '<span class=\'label bg-gray-300\'>${state}</span>'
            },
            filterable: {
                multiple: true,
                options: [
                    {label: '运行', value: 'UNDEFINED'},
                    {label: '成功', value: 'SUCCEEDED'},
                    {label: '失败', value: 'FAILED'},
                    {label: '终止', value: 'KILLED'},
                    {label: '结束', value: 'ENDED'},
                ]
            }
        },
        {
            type: "operation",
            label: "操作",
            width: 100,
            fixed: 'right',
            buttons: [
                /*{
                    disabled: true,
                    label: "停止",
                    type: "button",
                    level: "link",
                    tooltip: '从队列中移除该任务',
                    actionType: 'dialog',
                    dialog: {
                        closeOnEsc: true,
                        closeOnOutside: true,
                        size: 'sm',
                        close: true,
                        title: '停止确认',
                        body: '确认停止任务: <br>${name}<br> ?',
                        actions: [
                            {
                                type: 'button',
                                label: '取消',
                                actionType: 'cancel'
                            },
                            {
                                type: 'button',
                                label: '确认移除',
                                level: 'danger',
                                actionType: 'ajax',
                                api: '',
                                primary: true,
                                message: {
                                    success: '操作成功',
                                    failed: '操作失败'
                                }
                            }
                        ]
                    }
                },*/
                {
                    disabledOn: '${trackingUrl == null}',
                    disabledTip: '无应用页面',
                    label: "应用页面",
                    type: "action",
                    level: "link",
                    tooltip: '打开应用页面: ${trackingUrl}',
                    actionType: 'url',
                    url: '${trackingUrl}',
                    blank: true,
                }
            ]
        }
    ]
}

function simpleYarnDialog(mode, title) {
    return {
        title: title,
        actions: [],
        size: 'xl',
        body: [
            {
                type: 'service',
                body: [
                    {
                        type: 'tpl',
                        tpl: 'hello',
                        visibleOn: '${1 == 1}',
                    },
                    {
                        type: 'tpl',
                        tpl: 'hello',
                        visibleOn: '${1 == 2}',
                    },
                ],
            },
            {
                type: 'crud',
                api: {
                    method: 'get',
                    url: `\${base}/${mode}_yarn/job_list`,
                    data: {
                        page: '${page|default:undefined}',
                        count: '${perPage|default:undefined}',
                        order: '${orderBy|default:undefined}',
                        direction: '${orderDir|default:undefined}',
                        filter_state: '${state|default:undefined}',
                        filter_final_status: '${finalStatus|default:undefined}',
                        search_id: '${id|default:undefined}',
                        search_name: `\${${mode}JobName}`,
                        precise: true,
                    }
                },
                interval: 10000,
                syncLocation: false,
                silentPolling: true,
                resizable: false,
                perPage: 10,
                headerToolbar: [
                    "reload",
                    {
                        type: 'pagination',
                        layout: ['pager', 'perPage'],
                        maxButtons: 8,
                        showPageInput: false,
                    }
                ],
                footerToolbar: [],
                columns: yarnCrudColumns(),
            }
        ],
    }
}

function copyField(field, tips = '复制', ignoreLength = 0) {
    let tpl = ignoreLength === 0 ? `\${${field}}` : `\${TRUNCATE(${field}, ${ignoreLength})}`
    return {
        type: 'wrapper',
        size: 'none',
        body: [
            {
                type: 'tpl',
                className: 'mr-1',
                tpl: tpl,
            },
            {
                type: 'action',
                level: 'link',
                label: '',
                icon: 'fa fa-copy',
                size: 'xs',
                actionType: 'copy',
                content: `\$${field}`,
                tooltip: `${tips}`,
            },
        ]
    }
}

function flinkJobProperty(id, name, runMode) {
    return {
        type: 'property',
        title: 'Flink Job 配置',
        items: [
            {label: 'ID', content: copyField(id, '复制 ID')},
            {label: '任务名称', content: copyField(name, '复制任务名')},
            {
                label: '任务模式',
                content: {
                    ...runModeMapping(`${runMode}`)
                }
            },
        ],
    }
}

function flinkJobDialog() {
    return {
        title: 'Flink job 详情',
        actions: [],
        closeOnEsc: true,
        closeOnOutside: true,
        showCloseButton: false,
        size: 'md',
        body: [
            flinkJobProperty('flinkJobId', 'flinkJob.name', 'flinkJob.runMode'),
            {type: 'divider'},
            {
                type: 'action',
                label: '打开同步详情',
                actionType: 'dialog',
                dialog: simpleYarnDialog('sync', '同步详情')
            },
            {type: 'divider'},
            {
                type: 'service',
                api: {
                    method: 'get',
                    url: '${base}/table/list_metas',
                    data: {
                        flink_job_id: '${flinkJobId}'
                    },
                },
                canAccessSuperData: true,
                body: [
                    {
                        type: "table",
                        title: "包含 Hudi 同步表",
                        source: "${items}",
                        columns: [
                            {
                                label: '别名',
                                type: 'wrapper',
                                size: 'none',
                                body: [
                                    {
                                        type: 'action',
                                        level: 'link',
                                        label: '${tableMeta.alias}',
                                        size: 'xs',
                                        actionType: 'dialog',
                                        tooltip: '查看详情',
                                        dialog: tableMetaDialog(),
                                    },
                                    {
                                        type: 'action',
                                        level: 'link',
                                        label: '',
                                        icon: 'fa fa-copy',
                                        size: 'xs',
                                        actionType: 'copy',
                                        content: '${tableMeta.alias}',
                                        tooltip: '复制别名',
                                    },
                                ],
                            },
                            {
                                label: '并行度',
                                name: 'tableMeta.hudi.writeTasks',
                                align: 'center',
                            },
                            {
                                label: 'Bucket 数量',
                                name: 'tableMeta.hudi.bucketIndexNumber',
                                align: 'center',
                            },
                            {
                                label: '写并行度',
                                name: 'tableMeta.hudi.writeTasks',
                                align: 'center',
                            },
                            {
                                label: '压缩并行度',
                                name: 'tableMeta.hudi.compactionTasks',
                                align: 'center',
                            },
                        ]
                    }
                ]
            }
        ]
    }
}

function tableMetaDialog() {
    return {
        title: 'Table 详情',
        actions: [],
        closeOnEsc: true,
        closeOnOutside: true,
        showCloseButton: false,
        size: 'lg',
        body: [
            flinkJobProperty('flinkJobId', 'flinkJob.name', 'flinkJob.runMode'),
            {type: 'divider'},
            {
                type: 'property',
                title: 'Table 配置',
                items: [
                    {label: '别名', content: copyField('tableMeta.alias', '复制别名')},
                    {
                        label: '分片表',
                        content: '${IF(tableMeta.type === \'sharding\', \'是\', \'否\')}'
                    },
                    {label: '分区字段', content: copyField('tableMeta.partitionField', '复制分区字段')},
                    {label: '源端', content: copyField('tableMeta.source', '复制源端')},
                    {label: '源库名', content: copyField('tableMeta.schema', '复制库名')},
                    {label: '源表名', content: copyField('tableMeta.table', '复制表名')},
                    {label: '源表类型', content: '${tableMeta.sourceType}'},
                    {label: '优先级', content: '${tableMeta.priority}', span: 2},
                    {
                        label: '标签',
                        content: {
                            type: 'each',
                            source: '${SPLIT(tableMeta.tags, ",")}',
                            items: tagsMapping('item')
                        },
                        span: 3,
                    },
                    {label: '订阅 Topic', content: copyField('tableMeta.topic', '复制 Topic'), span: 3},
                    {
                        label: 'Pulsar 地址',
                        content: copyField('tableMeta.pulsarAddress', '复制地址', 130),
                        span: 3
                    },
                    {label: '过滤模式', content: filterModeMapping('tableMeta.filterType')},
                    {label: '过滤字段', content: '${tableMeta.filterField}', span: 2},
                    {
                        label: '过滤内容',
                        content: {
                            type: 'each',
                            source: '${SPLIT(tableMeta.filterValues, ",")}',
                            items: {
                                type: 'tpl',
                                tpl: "<span class='label bg-info mr-1'>${item}</span>",
                            }
                        },
                        span: 3,
                    },
                ],
            },
            {type: 'divider'},
            {
                type: 'property',
                title: 'Hudi 配置',
                items: [
                    {label: '表类型', content: hudiTableTypeMapping('tableMeta.hudi.targetTableType')},
                    {label: '库名', content: copyField('tableMeta.hudi.targetDataSource', '复制库名')},
                    {label: '表名', content: copyField('tableMeta.hudi.targetTable', '复制表名')},
                    {
                        label: 'HDFS',
                        content: copyField('tableMeta.hudi.targetHdfsPath', '复制路径'),
                        span: 3
                    },
                    {
                        label: 'Bucket 数量',
                        content: '${tableMeta.hudi.bucketIndexNumber}'
                    },
                    {
                        label: '保留文件版本',
                        content: '${tableMeta.hudi.keepFileVersion}'
                    },
                    {
                        label: '保留提交个数',
                        content: '${tableMeta.hudi.keepCommitVersion}'
                    },
                    {label: '读并行度', content: '${tableMeta.hudi.sourceTasks}'},
                    {label: '写并行度', content: '${tableMeta.hudi.writeTasks}'},
                    {
                        label: '压缩并行度',
                        content: '${tableMeta.hudi.compactionTasks}'
                    },
                    {
                        label: '写任务最大内存',
                        content: '${tableMeta.hudi. writeTaskMaxMemory}M'
                    },
                    {
                        label: '写批次大小',
                        content: '${tableMeta.hudi.writeBatchSize}M'
                    },
                    {
                        label: '写限速',
                        content: '${tableMeta.hudi.writeRateLimit}条/秒'
                    },
                    {
                        label: '压缩策略',
                        content: '${tableMeta.hudi. compactionStrategy}'
                    },
                    {
                        label: '压缩增量个数',
                        content: '${tableMeta.hudi.compactionDeltaCommits}'
                    },
                    {
                        label: '压缩增量时间',
                        content: '${tableMeta.hudi.compactionDeltaSeconds}秒'
                    },
                ],
            },
            {type: 'divider'},
            {
                type: 'property',
                title: 'Yarn 配置',
                column: 2,
                items: [
                    {
                        label: '同步 JM 内存',
                        content: '${tableMeta.syncYarn.jobManagerMemory}M'
                    },
                    {
                        label: '同步 TM 内存',
                        content: '${tableMeta.syncYarn.taskManagerMemory}M'
                    },
                    {
                        label: '压缩 JM 内存',
                        content: '${tableMeta.compactionYarn.jobManagerMemory}M'
                    },
                    {
                        label: '压缩 TM 内存',
                        content: '${tableMeta.compactionYarn.taskManagerMemory}M'
                    },
                ],
            },
            {type: 'divider'},
            {
                type: 'property',
                title: '其他配置',
                column: 4,
                items: [
                    {
                        label: '指标发布地址',
                        content: copyField('tableMeta.config.metricPublishUrl'),
                        span: 4
                    },
                    {
                        label: '指标打点延迟',
                        content: '${tableMeta.config.metricPublishDelay}'
                    },
                    {
                        label: '指标打点间隔',
                        content: '${tableMeta.config.metricPublishPeriod}'
                    },
                    {
                        label: '指标发布超时',
                        content: '${tableMeta.config.metricPublishTimeout}'
                    },
                    {
                        label: '指标批次数量',
                        content: '${tableMeta.config.metricPublishBatch}'
                    },
                    {
                        label: 'Prometheus 地址',
                        content: copyField('tableMeta.config.metricPrometheusUrl'),
                        span: 4
                    },
                    {
                        label: '事件提交服务地址',
                        content: copyField('tableMeta.config.metricApiUrl', '复制 URL', 130),
                        span: 4
                    },
                    {
                        label: 'Checkpoint 存储',
                        content: copyField('tableMeta.config.checkpointRootPath'),
                        span: 4
                    },
                ],
            },
            {type: 'divider'},
            {
                type: 'table',
                title: '表字段详情',
                source: '${tableMeta.fields}',
                resizable: false,
                columns: [
                    {name: 'sequence', label: '排序', width: 50, align: 'center'},
                    {name: 'name', label: '字段名'},
                    {name: 'type', label: '字段类型', width: 60},
                    {name: 'length', label: '字段长度', width: 60, align: 'center'},
                    {
                        label: '是否主键',
                        align: 'center',
                        width: 50,
                        type: 'tpl',
                        tpl: "${primaryKey|isTrue:'<i class=\"fa fa-check-circle text-success text-md p-0\"></i>':'<i></i>'|raw}",
                    },
                    {
                        label: '是否分片键',
                        align: 'center',
                        width: 70,
                        type: 'tpl',
                        tpl: "${partitionKey|isTrue:'<i class=\"fa fa-check-circle text-success text-md p-0\"></i>':'<i></i>'|raw}",
                    }
                ],
            }
        ],
    }
}

function runModeMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'ONE_IN_ONE': "<span class='label bg-pink-300'>1对1</span>",
            'ALL_IN_ONE': "<span class='label bg-purple-300'>1对多</span>",
            'ALL_IN_ONE_BY_TABLE': "<span class='label bg-cyan-300'>按表1对多</span>",
            'ALL_IN_ONE_BY_SCHEMA': "<span class='label bg-indigo-300'>按库1对多</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function compactionStatusMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'SCHEDULE': "<span class='label bg-info'>调度</span>",
            'START': "<span class='label'>开始</span>",
            'FINISH': "<span class='label bg-success'>完成</span>",
            'FAIL': "<span class='label bg-danger'>失败</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function tagsMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'NO_COMPACT': "<span class='label bg-info'>不压缩</span>",
            'PULSAR_BACKUP': "<span class='label bg-info'>备份Pulsar消息</span>",
            'NO_PRE_COMBINE': "<span class='label bg-info'>无预合并</span>",
            'NO_IGNORE_FAILED': "<span class='label bg-info'>不忽略写日志错误</span>",
            'DISABLE_CHAINING': "<span class='label bg-info'>取消算子合并</span>",
            'TRACE_LATEST_OP_TS': "<span class='label bg-info'>跟踪压缩op_ts</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function hudiTableTypeMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'MERGE_ON_READ': "<span class='label bg-info'>MOR</span>",
            'COPY_ON_WRITE': "<span class='label bg-info'>COW</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function filterModeMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'NONE': "<span class='label bg-pink-500'>无</span>",
            'INCLUDE': "<span class='label bg-purple-500'>包含模式</span>",
            'EXCLUDE': "<span class='label bg-cyan-500'>排除模式</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function subscriptionTypeMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'Exclusive': "<span class='label bg-pink-500'>独占</span>",
            'Shared': "<span class='label bg-purple-500'>共享</span>",
            'Failover': "<span class='label bg-cyan-500'>灾备</span>",
            'Key_Shared': "<span class='label bg-green-500'>Key</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}

function publishTypeMapping(field) {
    return {
        type: 'mapping',
        value: `\${${field}}`,
        map: {
            'Shared': "<span class='label bg-pink-500'>共享</span>",
            'Exclusive': "<span class='label bg-purple-500'>独占</span>",
            'WaiteForExclusive': "<span class='label bg-cyan-500'>等待独占</span>",
            '*': `<span class='label bg-gray-300'>\${${field}}</span>`
        },
    }
}
