// Copyright (C) 2018 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 {assertExists, assertTrue} from '../base/logging';
import {Engine} from '../common/engine';
import {Registry} from '../common/registry';
import {TraceTime, TrackState} from '../common/state';
import {fromNs, toNs} from '../common/time';
import {LIMIT, TrackData} from '../common/track_data';
import {globals} from '../frontend/globals';
import {publishTrackData} from '../frontend/publish';

import {Controller} from './controller';
import {ControllerFactory} from './controller';

interface TrackConfig {}

type TrackConfigWithNamespace = TrackConfig&{namespace: string};

// Allow to override via devtools for testing (note, needs to be done in the
// controller-thread).
(self as {} as {quantPx: number}).quantPx = 1;

// TrackController is a base class overridden by track implementations (e.g.,
// sched slices, nestable slices, counters).
export abstract class TrackController<
    Config extends TrackConfig, Data extends TrackData = TrackData> extends
    Controller<'main'> {
  readonly trackId: string;
  readonly engine: Engine;
  private data?: TrackData;
  private requestingData = false;
  private queuedRequest = false;
  private isSetup = false;
  private lastReloadHandled = 0;

  // We choose 100000 as the table size to cache as this is roughly the point
  // where SQLite sorts start to become expensive.
  private static readonly MIN_TABLE_SIZE_TO_CACHE = 100000;

  constructor(args: TrackControllerArgs) {
    super('main');
    this.trackId = args.trackId;
    this.engine = args.engine;
  }

  protected pxSize(): number {
    return (self as {} as {quantPx: number}).quantPx;
  }

  // Can be overriden by the track implementation to allow one time setup work
  // to be performed before the first onBoundsChange invcation.
  async onSetup() {}

  // Can be overriden by the track implementation to allow some one-off work
  // when requested reload (e.g. recalculating height).
  async onReload() {}

  // Must be overridden by the track implementation. Is invoked when the track
  // frontend runs out of cached data. The derived track controller is expected
  // to publish new track data in response to this call.
  abstract onBoundsChange(start: number, end: number, resolution: number):
      Promise<Data>;

  get trackState(): TrackState {
    return assertExists(globals.state.tracks[this.trackId]);
  }

  get config(): Config {
    return this.trackState.config as Config;
  }

  configHasNamespace(config: TrackConfig): config is TrackConfigWithNamespace {
    return 'namespace' in config;
  }

  namespaceTable(tableName: string): string {
    if (this.configHasNamespace(this.config)) {
      return this.config.namespace + '_' + tableName;
    } else {
      return tableName;
    }
  }

  publish(data: Data): void {
    this.data = data;
    publishTrackData({id: this.trackId, data});
  }

  // Returns a valid SQL table name with the given prefix that should be unique
  // for each track.
  tableName(prefix: string) {
    // Derive table name from, since that is unique for each track.
    // Track ID can be UUID but '-' is not valid for sql table name.
    const idSuffix = this.trackId.split('-').join('_');
    return `${prefix}_${idSuffix}`;
  }

  shouldSummarize(resolution: number): boolean {
    // |resolution| is in s/px (to nearest power of 10) assuming a display
    // of ~1000px 0.0008 is 0.8s.
    return resolution >= 0.0008;
  }

  protected async query(query: string) {
    const result = await this.engine.query(query);
    return result;
  }

  private shouldReload(): boolean {
    const {lastTrackReloadRequest} = globals.state;
    return !!lastTrackReloadRequest &&
        this.lastReloadHandled < lastTrackReloadRequest;
  }

  private markReloadHandled() {
    this.lastReloadHandled = globals.state.lastTrackReloadRequest || 0;
  }

  shouldRequestData(traceTime: TraceTime): boolean {
    if (this.data === undefined) return true;
    if (this.shouldReload()) return true;

    // If at the limit only request more data if the view has moved.
    const atLimit = this.data.length === LIMIT;
    if (atLimit) {
      // We request more data than the window, so add window duration to find
      // the previous window.
      const prevWindowStart =
          this.data.start + (traceTime.startSec - traceTime.endSec);
      return traceTime.startSec !== prevWindowStart;
    }

    // Otherwise request more data only when out of range of current data or
    // resolution has changed.
    const inRange = traceTime.startSec >= this.data.start &&
        traceTime.endSec <= this.data.end;
    return !inRange ||
        this.data.resolution !==
        globals.state.frontendLocalState.visibleState.resolution;
  }

  // Decides, based on the length of the trace and the number of rows
  // provided whether a TrackController subclass should cache its quantized
  // data. Returns the bucket size (in ns) if caching should happen and
  // undefined otherwise.
  // Subclasses should call this in their setup function
  cachedBucketSizeNs(numRows: number): number|undefined {
    // Ensure that we're not caching when the table size isn't even that big.
    if (numRows < TrackController.MIN_TABLE_SIZE_TO_CACHE) {
      return undefined;
    }

    const bounds = globals.state.traceTime;
    const traceDurNs = toNs(bounds.endSec - bounds.startSec);

    // For large traces, going through the raw table in the most zoomed-out
    // states can be very expensive as this can involve going through O(millions
    // of rows). The cost of this becomes high even for just iteration but is
    // especially slow as quantization involves a SQLite sort on the quantized
    // timestamp (for the group by).
    //
    // To get around this, we can cache a pre-quantized table which we can then
    // in zoomed-out situations and fall back to the real table when zoomed in
    // (which naturally constrains the amount of data by virtue of the window
    // covering a smaller timespan)
    //
    // This method computes that cached table by computing an approximation for
    // the bucket size we would use when totally zoomed out and then going a few
    // resolution levels down which ensures that our cached table works for more
    // than the literally most zoomed out state. Moving down a resolution level
    // is defined as moving down a power of 2; this matches the logic in
    // |globals.getCurResolution|.
    //
    // TODO(lalitm): in the future, we should consider having a whole set of
    // quantized tables each of which cover some portion of resolution lvel
    // range. As each table covers a large number of resolution levels, even 3-4
    // tables should really cover the all concievable trace sizes. This set
    // could be computed by looking at the number of events being processed one
    // level below the cached table and computing another layer of caching if
    // that count is too high (with respect to MIN_TABLE_SIZE_TO_CACHE).

    // 4k monitors have 3840 horizontal pixels so use that for a worst case
    // approximation of the window width.
    const approxWidthPx = 3840;

    // Compute the outermost bucket size. This acts as a starting point for
    // computing the cached size.
    const outermostResolutionLevel =
        Math.ceil(Math.log2(traceDurNs / approxWidthPx));
    const outermostBucketNs = Math.pow(2, outermostResolutionLevel);

    // This constant decides how many resolution levels down from our outermost
    // bucket computation we want to be able to use the cached table.
    // We've chosen 7 as it seems to be empircally seems to be a good fit for
    // trace data.
    const resolutionLevelsCovered = 7;

    // If we've got less resolution levels in the trace than the number of
    // resolution levels we want to go down, bail out because this cached
    // table is really not going to be used enough.
    if (outermostResolutionLevel < resolutionLevelsCovered) {
      return Number.MAX_SAFE_INTEGER;
    }

    // Another way to look at moving down resolution levels is to consider how
    // many sub-intervals we are splitting the bucket into.
    const bucketSubIntervals = Math.pow(2, resolutionLevelsCovered);

    // Calculate the smallest bucket we want our table to be able to handle by
    // dividing the outermsot bucket by the number of subintervals we should
    // divide by.
    const cachedBucketSizeNs = outermostBucketNs / bucketSubIntervals;

    // Our logic above should make sure this is an integer but double check that
    // here as an assertion before returning.
    assertTrue(Number.isInteger(cachedBucketSizeNs));

    return cachedBucketSizeNs;
  }

  run() {
    const visibleState = globals.state.frontendLocalState.visibleState;
    if (visibleState === undefined || visibleState.resolution === undefined ||
        visibleState.resolution === Infinity) {
      return;
    }
    const dur = visibleState.endSec - visibleState.startSec;
    if (globals.state.visibleTracks.includes(this.trackId) &&
        this.shouldRequestData(visibleState)) {
      if (this.requestingData) {
        this.queuedRequest = true;
      } else {
        this.requestingData = true;
        let promise = Promise.resolve();
        if (!this.isSetup) {
          promise = this.onSetup();
        } else if (this.shouldReload()) {
          promise = this.onReload().then(() => this.markReloadHandled());
        }
        promise
            .then(() => {
              this.isSetup = true;
              let resolution = visibleState.resolution;
              // TODO(hjd): We shouldn't have to be so defensive here.
              if (Math.log2(toNs(resolution)) % 1 !== 0) {
                // resolution is in pixels per second so 1000 means
                // 1px = 1ms.
                resolution =
                    fromNs(Math.pow(2, Math.floor(Math.log2(toNs(1000)))));
              }
              return this.onBoundsChange(
                  visibleState.startSec - dur,
                  visibleState.endSec + dur,
                  resolution);
            })
            .then((data) => {
              this.publish(data);
            })
            .finally(() => {
              this.requestingData = false;
              if (this.queuedRequest) {
                this.queuedRequest = false;
                this.run();
              }
            });
      }
    }
  }
}

export interface TrackControllerArgs {
  trackId: string;
  engine: Engine;
}

export interface TrackControllerFactory extends
    ControllerFactory<TrackControllerArgs> {
  kind: string;
}

export const trackControllerRegistry =
    Registry.kindRegistry<TrackControllerFactory>();
