// Copyright (C) 2023 The Android Open Source Project
//
// 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.

import m from 'mithril';

import {BigintMath} from '../base/bigint_math';
import {sqliteString} from '../base/string_utils';
import {duration, time} from '../base/time';
import {exists} from '../base/utils';
import {Anchor} from '../widgets/anchor';
import {MenuItem, PopupMenu2} from '../widgets/menu';
import {Section} from '../widgets/section';
import {SqlRef} from '../widgets/sql_ref';
import {Tree, TreeNode} from '../widgets/tree';

import {addTab} from './bottom_tab';
import {globals} from './globals';
import {SliceDetails} from './sql/slice';
import {
  BreakdownByThreadState,
  BreakdownByThreadStateTreeNode,
} from './sql/thread_state';
import {SqlTableTab} from './sql_table/tab';
import {SqlTables} from './sql_table/well_known_tables';
import {getProcessName, getThreadName} from './thread_and_process_info';
import {DurationWidget} from './widgets/duration';
import {Timestamp} from './widgets/timestamp';

function computeDuration(ts: time, dur: duration): m.Children {
  if (dur === -1n) {
    const minDuration = globals.state.traceTime.end - ts;
    return [m(DurationWidget, {dur: minDuration}), ' (Did not end)'];
  } else {
    return m(DurationWidget, {dur});
  }
}

// Renders a widget storing all of the generic details for a slice from the
// slice table.
export function renderDetails(
  slice: SliceDetails, durationBreakdown?: BreakdownByThreadState) {
  return m(
    Section,
    {title: 'Details'},
    m(
      Tree,
      m(TreeNode, {
        left: 'Name',
        right: m(
          PopupMenu2,
          {
            trigger: m(Anchor, slice.name),
          },
          m(MenuItem, {
            label: 'Slices with the same name',
            onclick: () => {
              addTab({
                kind: SqlTableTab.kind,
                config: {
                  table: SqlTables.slice,
                  displayName: 'slice',
                  filters: [`name = ${sqliteString(slice.name)}`],
                },
              });
            },
          }),
        ),
      }),
      m(TreeNode, {
        left: 'Category',
        right: !slice.category || slice.category === '[NULL]' ?
          'N/A' :
          slice.category,
      }),
      m(TreeNode, {
        left: 'Start time',
        right: m(Timestamp, {ts: slice.ts}),
      }),
      exists(slice.absTime) &&
              m(TreeNode, {left: 'Absolute Time', right: slice.absTime}),
      m(
        TreeNode,
        {
          left: 'Duration',
          right: computeDuration(slice.ts, slice.dur),
        },
        exists(durationBreakdown) && slice.dur > 0 &&
                  m(BreakdownByThreadStateTreeNode, {
                    data: durationBreakdown,
                    dur: slice.dur,
                  }),
      ),
      renderThreadDuration(slice),
      slice.thread && m(TreeNode, {
        left: 'Thread',
        right: getThreadName(slice.thread),
      }),
      slice.process && m(TreeNode, {
        left: 'Process',
        right: getProcessName(slice.process),
      }),
      slice.process && exists(slice.process.uid) && m(TreeNode, {
        left: 'User ID',
        right: slice.process.uid,
      }),
      slice.process && slice.process.packageName && m(TreeNode, {
        left: 'Package name',
        right: slice.process.packageName,
      }),
      slice.process && exists(slice.process.versionCode) && m(TreeNode, {
        left: 'Version code',
        right: slice.process.versionCode,
      }),
      m(TreeNode, {
        left: 'SQL ID',
        right: m(SqlRef, {table: 'slice', id: slice.id}),
      }),
    ));
}

function renderThreadDuration(sliceInfo: SliceDetails) {
  if (exists(sliceInfo.threadTs) && exists(sliceInfo.threadDur)) {
    // If we have valid thread duration, also display a percentage of
    // |threadDur| compared to |dur|.
    const ratio = BigintMath.ratio(sliceInfo.threadDur, sliceInfo.dur);
    const threadDurFractionSuffix =
        sliceInfo.threadDur === -1n ? '' : ` (${(ratio * 100).toFixed(2)}%)`;
    return m(TreeNode, {
      left: 'Thread duration',
      right: [
        computeDuration(sliceInfo.threadTs, sliceInfo.threadDur),
        threadDurFractionSuffix,
      ],
    });
  } else {
    return undefined;
  }
}
