/*

 * -------------------------------------------------------------------------

 * This file is part of the MindStudio project.

 * Copyright (c) 2025 Huawei Technologies Co.,Ltd.

 *

 * MindStudio is licensed under Mulan PSL v2.

 * You can use this software according to the terms and conditions of the Mulan PSL v2.

 * You may obtain a copy of Mulan PSL v2 at:

 *

 *          http://license.coscl.org.cn/MulanPSL2

 *

 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,

 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,

 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.

 * See the Mulan PSL v2 for more details.

 * -------------------------------------------------------------------------

 */



import { observer } from 'mobx-react';

import React, { useEffect, useState } from 'react';

import { useTranslation } from 'react-i18next';

import {

    useKernelDetails,

    queryKernelDetails,

    queryOneKernel,

    getPageData,

    querySystemViewDetails,

    queryFtraceStat,

    ftraceTimeSummaryColumns,

    ftraceIrqSummaryColumns,

    ftraceSchedSummaryColumns,

    pythonApiSummaryColumns,

    layerTypes,

    ftraceTypes,

} from './Common';

import type { CardMetaData } from '../../entity/data';

import { getDetailTimeDisplay } from '../../insight/units/AscendUnit';

import { getTimeOffset } from '../../insight/units/utils';

import { Button } from '@insight/lib/components';

import { ResizeTable } from '@insight/lib/resize';

import { StyledEmpty } from '@insight/lib/utils';

import { DETAIL_HEADER_HEIGHT_ETC_PX, BaseSummary, SelectContentViewProps } from './SystemView';

import { OverallMetrics } from './OverallMetrics';

import jumpToUnitOperator from '../../utils/jumpToUnitOperator';

import { ProjectType } from '../../entity/insight';

import { MemcpyOverallMetrics } from './MemcpyOverallMetrics';

import { KernelE2ETimeTable } from './KernelE2ETimeTable';



const filterColumn = [

    'name', 'type', 'acceleratorCore', 'taskId', 'inputShapes', 'inputDataTypes',

    'inputFormats', 'outputShapes', 'outputDataTypes', 'outputFormats',

];



const handleSelected = async(rowData: any, props: SelectContentViewProps): Promise<void> => {

    const res = await queryOneKernel({

        rankId: props.card.cardId,

        dbPath: props.card.dbPath,

        name: rowData.name,

        timestamp: rowData.startTime,

        duration: Number((rowData.duration * 1000).toFixed(0)),

    });



    jumpToUnitOperator({

        ...res,

        name: rowData.name,

        id: props.session.isFullDb as boolean ? rowData.id : res.id,

        cardId: props.card.cardId,

        dbPath: props.card.dbPath,

        tid: res.threadId,

        duration: Number((rowData.duration * 1000).toFixed(0)),

        timestamp: rowData.startTime,

        metaType: res.pid,

    });

};



const defaultFilters = {

    name: [],

    type: [],

    accCore: [],

    taskId: [],

    inputShapes: [],

    inputDataTypes: [],

    inputFormats: [],

    outputShapes: [],

    outputDataTypes: [],

    outputFormats: [],

};



const KernelDetails = observer((props: SelectContentViewProps) => {

    const defaultPage = { current: 1, pageSize: 10, total: 0 };

    const defaultSorter = { field: 'duration', order: 'descend' };

    const [dataSource, setDataSource] = useState<any[]>([]);

    const [page, setPage] = useState(defaultPage);

    const [sorter, setSorter] = useState(defaultSorter);

    const [filters, setFilters] = useState(defaultFilters);

    const [rowData, setRowData] = useState<any>({});

    const [loading, setLoading] = useState(false);

    const kernelDetails = useKernelDetails();

    const { t } = useTranslation('timeline', { keyPrefix: 'tableHead' });



    const status = props.session.units.find((unit: any) => (unit.metadata as CardMetaData).cardId === props.card.cardId)?.phase;

    useEffect(() => {

        updateData(page, sorter, filters);

    }, [sorter, filters, props.card.cardId, props.session.timeAnalysisRange]);

    useEffect(() => {

        if (status === 'download') {

            updateData(page, sorter, filters);

        }

    }, [status]);

    const updateData = async(pages: any, sorters: {field: string;order: string}, filtersConditions: any): Promise<void> => {

        const targetInfo = props.session.units.find(unitItem => (unitItem.metadata as CardMetaData)?.cardId === props.card?.cardId);

        if (props.card === undefined || props.card.cardId === '' || targetInfo?.projectType === ProjectType.IE) {

            setDataSource([]);

            setPage(defaultPage);

            return;

        }

        const filterTypes: string[] = [];

        Object.keys(filtersConditions).forEach(key => {

            const filterValue = filtersConditions[key];

            if (filterColumn.includes(key) && filterValue != null) {

                if (Array.isArray((filterValue)) && filterValue.length > 0) {

                    filterTypes.push(JSON.stringify({ columnName: key, value: filterValue[0] }));

                }

            }

        });

        setLoading(true);

        let startTime = props.session.timeAnalysisRange?.[0] ?? 0;

        startTime = startTime < 0 ? 0 : startTime;

        let endTime = props.session.timeAnalysisRange?.[1] ?? 0;

        endTime = endTime < 0 ? 0 : endTime;

        const timestampoffset = getTimeOffset(props.session, props.card);

        const sortedField = sorters.field === 'startTimeLabel' ? 'startTime' : sorters.field;

        const res = await queryKernelDetails({

            rankId: props.card.cardId,

            dbPath: props.card.dbPath,

            pageSize: pages.pageSize,

            current: pages.current,

            orderBy: sorters.order ? sortedField : defaultSorter.field,

            order: sorters.order ?? defaultSorter.order,

            startTime: Math.floor(startTime + timestampoffset),

            endTime: Math.ceil(endTime + timestampoffset),

            coreType: '',

            filterCondition: filterTypes,

        }).finally(() => {

            setLoading(false);

        });



        const data = res.kernelDetails.map((item: {

            startTimeLabel: string;

            startTime: number;}) => {

            item.startTimeLabel = getDetailTimeDisplay(item.startTime - timestampoffset);

            return item;

        });

        setDataSource(data);

        setPage({ ...page, total: res.count });

    };



    const colums = [

        ...kernelDetails,

        {

            title: t('Click To Timeline'),

            dataIndex: 'click',

            key: 'click',

            ellipsis: true,

            render: (_: any, record: any): JSX.Element => (<Button type="link"

                onClick={(): void => {

                    setRowData(record as any);

                }}>{t('Click')}</Button>),

        },

    ];



    useEffect(() => {

        if (rowData.name === null || rowData.name === undefined) {

            return;

        }

        handleSelected(rowData, props);

    }, [rowData]);

    return (

        (status === 'download' || props.card === undefined || props.card.cardId === '')

            ? <ResizeTable

                onChange={(pagination: any, newFilters: any, newSorter: any): void => {

                    setSorter(newSorter);

                    setFilters(newFilters);

                }}

                loading={loading}

                pagination={getPageData(page, setPage)}

                dataSource={dataSource}

                columns={colums}

                scroll={{ y: props.bottomHeight - DETAIL_HEADER_HEIGHT_ETC_PX }}

                rowClassName={(record: any): string => {

                    return record.id === rowData.id ? 'selected-row' : 'click-able';

                }}

                size="small"/>

            : <div style={{ display: 'flex', height: '100%' }}>

                <StyledEmpty style={{ margin: 'auto' }}/>

            </div>

    );

});



const ftraceColumnsMap: Record<string, typeof ftraceTimeSummaryColumns> = {

    'Ftrace Time Consuming': ftraceTimeSummaryColumns,

    'Ftrace IRQ': ftraceIrqSummaryColumns,

    'Ftrace Sched': ftraceSchedSummaryColumns,

};



export const StatsSystemView = [OverallMetrics, MemcpyOverallMetrics, ...ftraceTypes.map((type) => {

    return observer((props: SelectContentViewProps) => {

        const ftraceColumns = ftraceColumnsMap[type] || ftraceTimeSummaryColumns;

        if (props.session.isFullDb) {

            return <div style={{ display: 'flex', height: '100%' }}>

                <StyledEmpty style={{ margin: 'auto' }}/>

            </div>;

        }

        return (

            <BaseSummary

                layerType={type}

                request={queryFtraceStat}

                isStats={false}

                isFtrace={true}

                columns={ftraceColumns}

                {...props}

            />

        );

    });

}), ...layerTypes.map((type) => {

    return observer((props: SelectContentViewProps) => {

        return (

            <BaseSummary

                layerType={type}

                request={querySystemViewDetails}

                isStats={true}

                columns={pythonApiSummaryColumns}

                {...props}

            />

        );

    });

}), KernelE2ETimeTable, KernelDetails];