// 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 {RawQueryResult, TraceProcessor} from '../common/protos';
import {TimeSpan} from '../common/time';

/**
 * Abstract interface of a trace proccessor.
 * This class is wrapper for multiple proto services defined in:
 * //protos/perfetto/trace_processor/*
 * For each service ("FooService") Engine will have abstract getter
 * ("fooService") which returns a protobufjs rpc.Service object for
 * the given service.
 *
 * Engine also defines helpers for the most common service methods
 * (e.g. query).
 */
export abstract class Engine {
  abstract readonly id: string;

  /**
   * Push trace data into the engine. The engine is supposed to automatically
   * figure out the type of the trace (JSON vs Protobuf).
   */
  abstract parse(data: Uint8Array): void;

  /**
   * Notify the engine no more data is coming.
   */
  abstract notifyEof(): void;

  /*
   * The RCP interface to call service methods defined in trace_processor.proto.
   */
  abstract get rpc(): TraceProcessor;

  /**
   * Shorthand for sending a SQL query to the engine.
   * Exactly the same as engine.rpc.rawQuery({rawQuery});
   */
  query(sqlQuery: string): Promise<RawQueryResult> {
    return this.rpc.rawQuery({sqlQuery});
  }

  async queryOneRow(query: string): Promise<number[]> {
    const result = await this.query(query);
    const res: number[] = [];
    result.columns.map(c => res.push(+c.longValues![0]));
    return res;
  }

  // TODO(hjd): Maybe we should cache result? But then Engine must be
  // streaming aware.
  async getNumberOfCpus(): Promise<number> {
    const result =
        await this.query('select count(distinct(cpu)) as cpuCount from sched;');
    return +result.columns[0].longValues![0];
  }

  // TODO: This should live in code that's more specific to chrome, instead of
  // in engine.
  async getNumberOfProcesses(): Promise<number> {
    const result = await this.query('select count(*) from process;');
    return +result.columns[0].longValues![0];
  }

  async getTraceTimeBounds(): Promise<TimeSpan> {
    const maxQuery = 'select max(ts) from (select max(ts) as ts from sched ' +
        'union all select max(ts) as ts from slices)';
    const minQuery = 'select min(ts) from (select min(ts) as ts from sched ' +
        'union all select min(ts) as ts from slices)';
    const start = (await this.queryOneRow(minQuery))[0];
    const end = (await this.queryOneRow(maxQuery))[0];
    return new TimeSpan(start / 1e9, end / 1e9);
  }
}
