// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size 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 {Time, time} from '../base/time';
import {runQuery} from '../common/queries';
import {raf} from '../core/raf_scheduler';
import {Anchor} from '../widgets/anchor';
import {Button} from '../widgets/button';
import {DetailsShell} from '../widgets/details_shell';
import {GridLayout} from '../widgets/grid_layout';
import {Section} from '../widgets/section';
import {SqlRef} from '../widgets/sql_ref';
import {Tree, TreeNode} from '../widgets/tree';

import {BottomTab, bottomTabRegistry, NewBottomTabArgs} from './bottom_tab';
import {SchedSqlId, ThreadStateSqlId} from './sql_types';
import {
  getFullThreadName,
  getProcessName,
  getThreadName,
  ThreadInfo,
} from './thread_and_process_info';
import {
  getThreadState,
  getThreadStateFromConstraints,
  goToSchedSlice,
  ThreadState,
  ThreadStateRef,
} from './thread_state';
import {DurationWidget, renderDuration} from './widgets/duration';
import {Timestamp} from './widgets/timestamp';
import {addDebugSliceTrack} from './debug_tracks';

interface ThreadStateTabConfig {
  // Id into |thread_state| sql table.
  readonly id: ThreadStateSqlId;
}

interface RelatedThreadStates {
  prev?: ThreadState;
  next?: ThreadState;
  waker?: ThreadState;
  wakee?: ThreadState[];
}

export class ThreadStateTab extends BottomTab<ThreadStateTabConfig> {
  static readonly kind = 'dev.perfetto.ThreadStateTab';

  state?: ThreadState;
  relatedStates?: RelatedThreadStates;
  loaded: boolean = false;

  static create(args: NewBottomTabArgs<ThreadStateTabConfig>): ThreadStateTab {
    return new ThreadStateTab(args);
  }

  constructor(args: NewBottomTabArgs<ThreadStateTabConfig>) {
    super(args);

    this.load().then(() => {
      this.loaded = true;
      raf.scheduleFullRedraw();
    });
  }

  async load() {
    this.state = await getThreadState(this.engine, this.config.id);

    if (!this.state) {
      return;
    }

    const relatedStates: RelatedThreadStates = {};
    relatedStates.prev = (
      await getThreadStateFromConstraints(this.engine, {
        filters: [
          `ts + dur = ${this.state.ts}`,
          `utid = ${this.state.thread?.utid}`,
        ],
        limit: 1,
      })
    )[0];
    relatedStates.next = (
      await getThreadStateFromConstraints(this.engine, {
        filters: [
          `ts = ${this.state.ts + this.state.dur}`,
          `utid = ${this.state.thread?.utid}`,
        ],
        limit: 1,
      })
    )[0];
    if (this.state.wakerThread?.utid !== undefined) {
      relatedStates.waker = (
        await getThreadStateFromConstraints(this.engine, {
          filters: [
            `utid = ${this.state.wakerThread?.utid}`,
            `ts <= ${this.state.ts}`,
            `ts + dur >= ${this.state.ts}`,
          ],
        })
      )[0];
    }
    relatedStates.wakee = await getThreadStateFromConstraints(this.engine, {
      filters: [
        `waker_utid = ${this.state.thread?.utid}`,
        `state = 'R'`,
        `ts >= ${this.state.ts}`,
        `ts <= ${this.state.ts + this.state.dur}`,
      ],
    });

    this.relatedStates = relatedStates;
  }

  getTitle() {
    // TODO(altimin): Support dynamic titles here.
    return 'Current Selection';
  }

  viewTab() {
    // TODO(altimin/stevegolton): Differentiate between "Current Selection" and
    // "Pinned" views in DetailsShell.
    return m(
      DetailsShell,
      {title: 'Thread State', description: this.renderLoadingText()},
      m(
        GridLayout,
        m(
          Section,
          {title: 'Details'},
          this.state && this.renderTree(this.state),
        ),
        m(
          Section,
          {title: 'Related thread states'},
          this.renderRelatedThreadStates(),
        ),
      ),
    );
  }

  private renderLoadingText() {
    if (!this.loaded) {
      return 'Loading';
    }
    if (!this.state) {
      return `Thread state ${this.config.id} does not exist`;
    }
    // TODO(stevegolton): Return something intelligent here.
    return this.config.id;
  }

  private renderTree(state: ThreadState) {
    const thread = state.thread;
    const process = state.thread?.process;
    return m(
      Tree,
      m(TreeNode, {
        left: 'Start time',
        right: m(Timestamp, {ts: state.ts}),
      }),
      m(TreeNode, {
        left: 'Duration',
        right: m(DurationWidget, {dur: state.dur}),
      }),
      m(TreeNode, {
        left: 'State',
        right: this.renderState(
          state.state,
          state.cpu,
          state.schedSqlId,
          state.ts,
        ),
      }),
      state.blockedFunction &&
        m(TreeNode, {
          left: 'Blocked function',
          right: state.blockedFunction,
        }),
      process &&
        m(TreeNode, {
          left: 'Process',
          right: getProcessName(process),
        }),
      thread && m(TreeNode, {left: 'Thread', right: getThreadName(thread)}),
      state.wakerThread && this.renderWakerThread(state.wakerThread),
      m(TreeNode, {
        left: 'SQL ID',
        right: m(SqlRef, {table: 'thread_state', id: state.threadStateSqlId}),
      }),
    );
  }

  private renderState(
    state: string,
    cpu: number | undefined,
    id: SchedSqlId | undefined,
    ts: time,
  ): m.Children {
    if (!state) {
      return null;
    }
    if (id === undefined || cpu === undefined) {
      return state;
    }
    return m(
      Anchor,
      {
        title: 'Go to CPU slice',
        icon: 'call_made',
        onclick: () => goToSchedSlice(cpu, id, ts),
      },
      `${state} on CPU ${cpu}`,
    );
  }

  private renderWakerThread(wakerThread: ThreadInfo) {
    return m(
      TreeNode,
      {left: 'Waker'},
      m(TreeNode, {
        left: 'Process',
        right: getProcessName(wakerThread.process),
      }),
      m(TreeNode, {left: 'Thread', right: getThreadName(wakerThread)}),
    );
  }

  private renderRelatedThreadStates(): m.Children {
    if (this.state === undefined || this.relatedStates === undefined) {
      return 'Loading';
    }
    const startTs = this.state.ts;
    const renderRef = (state: ThreadState, name?: string) =>
      m(ThreadStateRef, {
        id: state.threadStateSqlId,
        ts: state.ts,
        dur: state.dur,
        utid: state.thread!.utid,
        name,
      });

    const sliceColumns = {ts: 'ts', dur: 'dur', name: 'name'};
    const sliceColumnNames = ['id', 'utid', 'ts', 'dur', 'name', 'table_name'];

    const sliceLiteColumns = {ts: 'ts', dur: 'dur', name: 'thread_name'};
    const sliceLiteColumnNames = [
      'id',
      'utid',
      'ts',
      'dur',
      'thread_name',
      'process_name',
      'table_name',
    ];

    const nameForNextOrPrev = (state: ThreadState) =>
      `${state.state} for ${renderDuration(state.dur)}`;
    return [
      m(
        Tree,
        this.relatedStates.waker &&
          m(TreeNode, {
            left: 'Waker',
            right: renderRef(
              this.relatedStates.waker,
              getFullThreadName(this.relatedStates.waker.thread),
            ),
          }),
        this.relatedStates.prev &&
          m(TreeNode, {
            left: 'Previous state',
            right: renderRef(
              this.relatedStates.prev,
              nameForNextOrPrev(this.relatedStates.prev),
            ),
          }),
        this.relatedStates.next &&
          m(TreeNode, {
            left: 'Next state',
            right: renderRef(
              this.relatedStates.next,
              nameForNextOrPrev(this.relatedStates.next),
            ),
          }),
        this.relatedStates.wakee &&
          this.relatedStates.wakee.length > 0 &&
          m(
            TreeNode,
            {
              left: 'Woken threads',
            },
            this.relatedStates.wakee.map((state) =>
              m(TreeNode, {
                left: m(Timestamp, {
                  ts: state.ts,
                  display: [
                    'Start+',
                    m(DurationWidget, {dur: Time.sub(state.ts, startTs)}),
                  ],
                }),
                right: renderRef(state, getFullThreadName(state.thread)),
              }),
            ),
          ),
      ),
      m(Button, {
        label: 'Critical path lite',
        onclick: () =>
          runQuery(
            `INCLUDE PERFETTO MODULE sched.thread_executing_span;`,
            this.engine,
          ).then(() =>
            addDebugSliceTrack(
              this.engine,
              {
                sqlSource: `
                    SELECT
                      cr.id,
                      cr.utid,
                      cr.ts,
                      cr.dur,
                      thread.name AS thread_name,
                      process.name AS process_name,
                      'thread_state' AS table_name
                    FROM
                      _thread_executing_span_critical_path(
                        ${this.state?.thread?.utid},
                        trace_bounds.start_ts,
                        trace_bounds.end_ts - trace_bounds.start_ts) cr,
                      trace_bounds
                    JOIN thread USING(utid)
                    JOIN process USING(upid)
                  `,
                columns: sliceLiteColumnNames,
              },
              `${this.state?.thread?.name}`,
              sliceLiteColumns,
              sliceLiteColumnNames,
            ),
          ),
      }),
      m(Button, {
        label: 'Critical path',
        onclick: () =>
          runQuery(
            `INCLUDE PERFETTO MODULE sched.thread_executing_span;`,
            this.engine,
          ).then(() =>
            addDebugSliceTrack(
              this.engine,
              {
                sqlSource: `
                    SELECT cr.id, cr.utid, cr.ts, cr.dur, cr.name, cr.table_name
                      FROM
                        _thread_executing_span_critical_path_stack(
                          ${this.state?.thread?.utid},
                          trace_bounds.start_ts,
                          trace_bounds.end_ts - trace_bounds.start_ts) cr,
                        trace_bounds WHERE name IS NOT NULL
                  `,
                columns: sliceColumnNames,
              },
              `${this.state?.thread?.name}`,
              sliceColumns,
              sliceColumnNames,
            ),
          ),
      }),
    ];
  }

  isLoading() {
    return this.state === undefined || this.relatedStates === undefined;
  }
}

bottomTabRegistry.register(ThreadStateTab);
