// Copyright (C) 2022 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 {defer, Deferred} from '../../base/deferred';
import {assertExists, assertTrue} from '../../base/logging';
import {binaryDecode, binaryEncode} from '../../base/string_utils';
import {
  ChromeExtensionMessage,
  isChromeExtensionError,
  isChromeExtensionStatus,
  isGetCategoriesResponse,
} from '../../controller/chrome_proxy_record_controller';
import {
  isDisableTracingResponse,
  isEnableTracingResponse,
  isFreeBuffersResponse,
  isGetTraceStatsResponse,
  isReadBuffersResponse,
} from '../../controller/consumer_port_types';
import {
  EnableTracingRequest,
  IBufferStats,
  ISlice,
  TraceConfig,
} from '../protos';
import {RecordingError} from './recording_error_handling';
import {
  TracingSession,
  TracingSessionListener,
} from './recording_interfaces_v2';
import {
  BUFFER_USAGE_INCORRECT_FORMAT,
  BUFFER_USAGE_NOT_ACCESSIBLE,
  EXTENSION_ID,
  MALFORMED_EXTENSION_MESSAGE,
} from './recording_utils';

// This class implements the protocol described in
// https://perfetto.dev/docs/design-docs/api-and-abi#tracing-protocol-abi
// However, with the Chrome extension we communicate using JSON messages.
export class ChromeTracedTracingSession implements TracingSession {
  // Needed for ReadBufferResponse: all the trace packets are split into
  // several slices. |partialPacket| is the buffer for them. Once we receive a
  // slice with the flag |lastSliceForPacket|, a new packet is created.
  private partialPacket: ISlice[] = [];

  // For concurrent calls to 'GetCategories', we return the same value.
  private pendingGetCategoriesMessage?: Deferred<string[]>;

  private pendingStatsMessages = new Array<Deferred<IBufferStats[]>>();

  // Port through which we communicate with the extension.
  private chromePort: chrome.runtime.Port;
  // True when Perfetto is connected via the port to the tracing session.
  private isPortConnected: boolean;

  constructor(private tracingSessionListener: TracingSessionListener) {
    this.chromePort = chrome.runtime.connect(EXTENSION_ID);
    this.isPortConnected = true;
  }

  start(config: TraceConfig): void {
    if (!this.isPortConnected) return;
    const duration = config.durationMs;
    this.tracingSessionListener.onStatus(`Recording in progress${
        duration ? ' for ' + duration.toString() + ' ms' : ''}...`);

    const enableTracingRequest = new EnableTracingRequest();
    enableTracingRequest.traceConfig = config;
    const enableTracingRequestProto = binaryEncode(
        EnableTracingRequest.encode(enableTracingRequest).finish());
    this.chromePort.postMessage(
        {method: 'EnableTracing', requestData: enableTracingRequestProto});
  }

  // The 'cancel' method will end the tracing session and will NOT return the
  // trace. Therefore, we do not need to keep the connection open.
  cancel(): void {
    if (!this.isPortConnected) return;
    this.terminateConnection();
  }

  // The 'stop' method will end the tracing session and cause the trace to be
  // returned via a callback. We maintain the connection to the target so we can
  // extract the trace.
  // See 'DisableTracing' in:
  // https://perfetto.dev/docs/design-docs/life-of-a-tracing-session
  stop(): void {
    if (!this.isPortConnected) return;
    this.chromePort.postMessage({method: 'DisableTracing'});
  }

  getCategories(): Promise<string[]> {
    if (!this.isPortConnected) {
      throw new RecordingError(
          'Attempting to get categories from a ' +
          'disconnected tracing session.');
    }
    if (this.pendingGetCategoriesMessage) {
      return this.pendingGetCategoriesMessage;
    }

    this.chromePort.postMessage({method: 'GetCategories'});
    return this.pendingGetCategoriesMessage = defer<string[]>();
  }

  async getTraceBufferUsage(): Promise<number> {
    if (!this.isPortConnected) return 0;
    const bufferStats = await this.getBufferStats();
    let percentageUsed = -1;
    for (const buffer of bufferStats) {
      const used = assertExists(buffer.bytesWritten);
      const total = assertExists(buffer.bufferSize);
      if (total >= 0) {
        percentageUsed = Math.max(percentageUsed, used / total);
      }
    }

    if (percentageUsed === -1) {
      throw new RecordingError(BUFFER_USAGE_INCORRECT_FORMAT);
    }
    return percentageUsed;
  }

  initConnection(): void {
    this.chromePort.onMessage.addListener((message: ChromeExtensionMessage) => {
      this.handleExtensionMessage(message);
    });
  }

  private getBufferStats(): Promise<IBufferStats[]> {
    this.chromePort.postMessage({method: 'GetTraceStats'});

    const statsMessage = defer<IBufferStats[]>();
    this.pendingStatsMessages.push(statsMessage);
    return statsMessage;
  }

  private terminateConnection(): void {
    this.chromePort.postMessage({method: 'FreeBuffers'});
    this.clearState();
  }

  private clearState() {
    this.chromePort.disconnect();
    this.isPortConnected = false;
    for (const statsMessage of this.pendingStatsMessages) {
      statsMessage.reject(new RecordingError(BUFFER_USAGE_NOT_ACCESSIBLE));
    }
    this.pendingStatsMessages = [];
    this.pendingGetCategoriesMessage = undefined;
  }

  private handleExtensionMessage(message: ChromeExtensionMessage) {
    if (isChromeExtensionError(message)) {
      this.terminateConnection();
      this.tracingSessionListener.onError(message.error);
    } else if (isChromeExtensionStatus(message)) {
      this.tracingSessionListener.onStatus(message.status);
    } else if (isReadBuffersResponse(message)) {
      if (!message.slices) {
        return;
      }
      for (const messageSlice of message.slices) {
        // The extension sends the binary data as a string.
        // see http://shortn/_oPmO2GT6Vb
        if (typeof messageSlice.data !== 'string') {
          throw new RecordingError(MALFORMED_EXTENSION_MESSAGE);
        }
        const decodedSlice = {
          data: binaryDecode(messageSlice.data),
        };
        this.partialPacket.push(decodedSlice);
        if (messageSlice.lastSliceForPacket) {
          let bufferSize = 0;
          for (const slice of this.partialPacket) {
            bufferSize += slice.data!.length;
          }

          const completeTrace = new Uint8Array(bufferSize);
          let written = 0;
          for (const slice of this.partialPacket) {
            const data = slice.data!;
            completeTrace.set(data, written);
            written += data.length;
          }
          // The trace already comes encoded as a proto.
          this.tracingSessionListener.onTraceData(completeTrace);
          this.terminateConnection();
        }
      }
    } else if (isGetCategoriesResponse(message)) {
      assertExists(this.pendingGetCategoriesMessage)
          .resolve(message.categories);
      this.pendingGetCategoriesMessage = undefined;
    } else if (isEnableTracingResponse(message)) {
      // Once the service notifies us that a tracing session is enabled,
      // we can start streaming the response using 'ReadBuffers'.
      this.chromePort.postMessage({method: 'ReadBuffers'});
    } else if (isGetTraceStatsResponse(message)) {
      const maybePendingStatsMessage = this.pendingStatsMessages.shift();
      if (maybePendingStatsMessage) {
        maybePendingStatsMessage.resolve(
            message?.traceStats?.bufferStats || []);
      }
    } else if (isFreeBuffersResponse(message)) {
      // No action required. If we successfully read a whole trace,
      // we close the connection. Alternatively, if the tracing finishes
      // with an exception or if the user cancels it, we also close the
      // connection.
    } else {
      assertTrue(isDisableTracingResponse(message));
      // No action required. Same reasoning as for FreeBuffers.
    }
  }
}
