// 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 {Actions} from '../common/actions';
import {EngineProxy} from '../common/engine';
import {LONG, NUM, NUM_NULL, STR_NULL} from '../common/query_result';
import {translateState} from '../common/thread_state';
import {fromNs, timeToCode} from '../common/time';

import {copyToClipboard} from './clipboard';
import {globals} from './globals';
import {menuItem} from './popup_menu';
import {scrollToTrackAndTs} from './scroll_helper';
import {
  asUtid,
  SchedSqlId,
  ThreadStateSqlId,
  timestampFromNanos,
  toTraceTime,
  TPTimestamp,
} from './sql_types';
import {
  constraintsToQueryFragment,
  fromNumNull,
  SQLConstraints,
} from './sql_utils';
import {
  getProcessName,
  getThreadInfo,
  getThreadName,
  ThreadInfo,
} from './thread_and_process_info';
import {dict, Dict, maybeValue, Value, value} from './value';

// Representation of a single thread state object, corresponding to
// a row for the |thread_slice| table.
export interface ThreadState {
  // Id into |thread_state| table.
  threadStateSqlId: ThreadStateSqlId;
  // Id of the corresponding entry in the |sched| table.
  schedSqlId?: SchedSqlId;
  // Timestamp of the beginning of this thread state in nanoseconds.
  ts: TPTimestamp;
  // Duration of this thread state in nanoseconds.
  dur: number;
  // CPU id if this thread state corresponds to a thread running on the CPU.
  cpu?: number;
  // Human-readable name of this thread state.
  state: string;
  blockedFunction?: string;

  thread?: ThreadInfo;
  wakerThread?: ThreadInfo;
}

// Gets a list of thread state objects from Trace Processor with given
// constraints.
export async function getThreadStateFromConstraints(
    engine: EngineProxy, constraints: SQLConstraints): Promise<ThreadState[]> {
  const query = await engine.query(`
    SELECT
      thread_state.id as threadStateSqlId,
      (select sched.id
        from sched
        where sched.ts=thread_state.ts and sched.utid=thread_state.utid
        limit 1
       ) as schedSqlId,
      ts,
      thread_state.dur as dur,
      thread_state.cpu as cpu,
      state,
      thread_state.blocked_function as blockedFunction,
      io_wait as ioWait,
      thread_state.utid as utid,
      waker_utid as wakerUtid
    FROM thread_state
    ${constraintsToQueryFragment(constraints)}`);
  const it = query.iter({
    threadStateSqlId: NUM,
    schedSqlId: NUM_NULL,
    ts: LONG,
    dur: NUM,
    cpu: NUM_NULL,
    state: STR_NULL,
    blockedFunction: STR_NULL,
    ioWait: NUM_NULL,
    utid: NUM,
    wakerUtid: NUM_NULL,
  });

  const result: ThreadState[] = [];

  for (; it.valid(); it.next()) {
    const ioWait = it.ioWait === null ? undefined : it.ioWait > 0;
    const wakerUtid = asUtid(it.wakerUtid || undefined);

    // TODO(altimin): Consider fetcing thread / process info using a single
    // query instead of one per row.
    result.push({
      threadStateSqlId: it.threadStateSqlId as ThreadStateSqlId,
      schedSqlId: fromNumNull(it.schedSqlId) as (SchedSqlId | undefined),
      ts: timestampFromNanos(it.ts),
      dur: it.dur,
      cpu: fromNumNull(it.cpu),
      state: translateState(it.state || undefined, ioWait),
      blockedFunction: it.blockedFunction || undefined,
      thread: await getThreadInfo(engine, asUtid(it.utid)),
      wakerThread: wakerUtid ? await getThreadInfo(engine, wakerUtid) :
                               undefined,
    });
  }
  return result;
}

export async function getThreadState(
    engine: EngineProxy, id: number): Promise<ThreadState|undefined> {
  const result = await getThreadStateFromConstraints(engine, {
    filters: [`id=${id}`],
  });
  if (result.length > 1) {
    throw new Error(`thread_state table has more than one row with id ${id}`);
  }
  if (result.length === 0) {
    return undefined;
  }
  return result[0];
}

export function goToSchedSlice(cpu: number, id: SchedSqlId, ts: TPTimestamp) {
  let trackId: string|undefined;
  for (const track of Object.values(globals.state.tracks)) {
    if (track.kind === 'CpuSliceTrack' &&
        (track.config as {cpu: number}).cpu === cpu) {
      trackId = track.id;
    }
  }
  if (trackId === undefined) {
    return;
  }
  globals.makeSelection(Actions.selectSlice({id, trackId}));
  // TODO(stevegolton): scrollToTrackAndTs() should take a TPTimestamp
  scrollToTrackAndTs(trackId, Number(ts));
}

function stateToValue(
    state: string,
    cpu: number|undefined,
    id: SchedSqlId|undefined,
    ts: TPTimestamp): Value|null {
  if (!state) {
    return null;
  }
  if (id === undefined || cpu === undefined) {
    return value(state);
  }
  return value(`${state} on CPU ${cpu}`, {
    rightButton: {
      action: () => {
        goToSchedSlice(cpu, id, ts);
      },
      hoverText: 'Go to CPU slice',
    },
  });
}

export function threadStateToDict(state: ThreadState): Dict {
  const result: {[name: string]: Value|null} = {};

  result['Start time'] = value(timeToCode(toTraceTime(state.ts)));
  result['Duration'] = value(timeToCode(fromNs(state.dur)));
  result['State'] =
      stateToValue(state.state, state.cpu, state.schedSqlId, state.ts);
  result['Blocked function'] = maybeValue(state.blockedFunction);
  const process = state?.thread?.process;
  result['Process'] = maybeValue(process ? getProcessName(process) : undefined);
  const thread = state?.thread;
  result['Thread'] = maybeValue(thread ? getThreadName(thread) : undefined);
  if (state.wakerThread) {
    const process = state.wakerThread.process;
    result['Waker'] = dict({
      'Process': maybeValue(process ? getProcessName(process) : undefined),
      'Thread': maybeValue(getThreadName(state.wakerThread)),
    });
  }
  result['SQL id'] = value(`thread_state[${state.threadStateSqlId}]`, {
    contextMenu: [
      menuItem(
          'Copy SQL query',
          () => {
            copyToClipboard(`select * from thread_state where id=${
                state.threadStateSqlId}`);
          }),
    ],
  });

  return dict(result);
}
