// 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 {Engine} from '../common/engine';
import {NUM, STR, STR_NULL} from '../common/query_result';
import {FtraceFilterState, Pagination} from '../common/state';
import {TimeSpan, toNsCeil, toNsFloor} from '../common/time';
import {FtraceEvent, globals} from '../frontend/globals';
import {publishFtracePanelData} from '../frontend/publish';
import {ratelimit} from '../frontend/rate_limiters';

import {Controller} from './controller';

export interface FtraceControllerArgs {
  engine: Engine;
}

interface RetVal {
  events: FtraceEvent[];
  offset: number;
  numEvents: number;
}

export class FtraceController extends Controller<'main'> {
  private engine: Engine;
  private oldSpan: TimeSpan = new TimeSpan(0, 0);
  private oldFtraceFilter?: FtraceFilterState;
  private oldPagination?: Pagination;

  constructor({engine}: FtraceControllerArgs) {
    super('main');
    this.engine = engine;
  }

  run() {
    if (this.shouldUpdate()) {
      this.oldSpan = globals.frontendLocalState.visibleWindowTime.clone();
      this.oldFtraceFilter = globals.state.ftraceFilter;
      this.oldPagination = globals.state.ftracePagination;
      if (globals.state.ftracePagination.count > 0) {
        this.lookupFtraceEventsRateLimited();
      }
    }
  }

  private lookupFtraceEventsRateLimited = ratelimit(() => {
    const {offset, count} = globals.state.ftracePagination;
    // The formatter doesn't like formatted chained methods :(
    const promise = this.lookupFtraceEvents(offset, count);
    promise.then(({events, offset, numEvents}: RetVal) => {
      publishFtracePanelData({events, offset, numEvents});
    });
  }, 250);

  private shouldUpdate(): boolean {
    // Has the visible window moved?
    const visibleWindow = globals.frontendLocalState.visibleWindowTime;
    if (this.oldSpan.start !== visibleWindow.start ||
        this.oldSpan.end !== visibleWindow.end) {
      return true;
    }

    // Has the pagination changed?
    if (this.oldPagination !== globals.state.ftracePagination) {
      return true;
    }

    // Has the filter changed?
    if (this.oldFtraceFilter !== globals.state.ftraceFilter) {
      return true;
    }

    return false;
  }

  async lookupFtraceEvents(offset: number, count: number): Promise<RetVal> {
    const appState = globals.state;
    const frontendState = globals.frontendLocalState;
    const {start, end} = frontendState.visibleWindowTime;

    const startNs = toNsFloor(start);
    const endNs = toNsCeil(end);

    const excludeList = appState.ftraceFilter.excludedNames;
    const excludeListSql = excludeList.map((s) => `'${s}'`).join(',');

    // TODO(stevegolton): This query can be slow when traces are huge.
    // The number of events is only used for correctly sizing the panel's
    // scroll container so that the scrollbar works as if the panel were fully
    // populated.
    // Perhaps we could work out some UX that doesn't need this.
    let queryRes = await this.engine.query(`
      select count(id) as numEvents
      from ftrace_event
      where
        ftrace_event.name not in (${excludeListSql}) and
        ts >= ${startNs} and ts <= ${endNs}
      `);
    const {numEvents} = queryRes.firstRow({numEvents: NUM});

    queryRes = await this.engine.query(`
      select
        ftrace_event.id as id,
        ftrace_event.ts as ts,
        ftrace_event.name as name,
        ftrace_event.cpu as cpu,
        thread.name as thread,
        process.name as process,
        to_ftrace(ftrace_event.id) as args
      from ftrace_event
      left join thread
      on ftrace_event.utid = thread.utid
      left join process
      on thread.upid = process.upid
      where
        ftrace_event.name not in (${excludeListSql}) and
        ts >= ${startNs} and ts <= ${endNs}
      order by id
      limit ${count} offset ${offset};`);
    const events: FtraceEvent[] = [];
    const it = queryRes.iter(
        {
          id: NUM,
          ts: NUM,
          name: STR,
          cpu: NUM,
          thread: STR_NULL,
          process: STR_NULL,
          args: STR,
        },
    );
    for (let row = 0; it.valid(); it.next(), row++) {
      events.push({
        id: it.id,
        ts: it.ts,
        name: it.name,
        cpu: it.cpu,
        thread: it.thread,
        process: it.process,
        args: it.args,
      });
    }
    return {events, offset, numEvents};
  }
};
