// 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 {_TextDecoder} from 'custom_utils';

import {defer, Deferred} from '../../base/deferred';
import {assertFalse} from '../../base/logging';
import {ArrayBufferBuilder} from '../array_buffer_builder';

import {RecordingError} from './recording_error_handling';
import {ByteStream} from './recording_interfaces_v2';
import {
  BINARY_PUSH_FAILURE,
  BINARY_PUSH_UNKNOWN_RESPONSE,
} from './recording_utils';

// https://cs.android.com/android/platform/superproject/+/master:packages/
// modules/adb/file_sync_protocol.h;l=144
const MAX_SYNC_SEND_CHUNK_SIZE = 64 * 1024;

// Adb does not accurately send some file permissions. If you need a special set
// of permissions, do not rely on this value. Rather, send a shell command which
// explicitly sets permissions, such as:
// 'shell:chmod ${permissions} ${path}'
const FILE_PERMISSIONS = 2 ** 15 + 0o644;

const textDecoder = new _TextDecoder();

// For details about the protocol, see:
// https://cs.android.com/android/platform/superproject/+/master:packages/modules/adb/SYNC.TXT
export class AdbFileHandler {
  private sentByteCount = 0;
  private isPushOngoing: boolean = false;

  constructor(private byteStream: ByteStream) {}

  async pushBinary(binary: Uint8Array, path: string): Promise<void> {
    // For a given byteStream, we only support pushing one binary at a time.
    assertFalse(this.isPushOngoing);
    this.isPushOngoing = true;
    const transferFinished = defer<void>();

    this.byteStream.addOnStreamDataCallback(
        (data) => this.onStreamData(data, transferFinished));
    this.byteStream.addOnStreamCloseCallback(() => this.isPushOngoing = false);

    const sendMessage = new ArrayBufferBuilder();
    // 'SEND' is the API method used to send a file to device.
    sendMessage.append('SEND');
    // The remote file name is split into two parts separated by the last
    // comma (","). The first part is the actual path, while the second is a
    // decimal encoded file mode containing the permissions of the file on
    // device.
    sendMessage.append(path.length + 6);
    sendMessage.append(path);
    sendMessage.append(',');
    sendMessage.append(FILE_PERMISSIONS.toString());
    this.byteStream.write(new Uint8Array(sendMessage.toArrayBuffer()));

    while (!(await this.sendNextDataChunk(binary)))
      ;

    return transferFinished;
  }

  private onStreamData(data: Uint8Array, transferFinished: Deferred<void>) {
    this.sentByteCount = 0;
    const response = textDecoder.decode(data);
    if (response.split('\n')[0].includes('FAIL')) {
      // Sample failure response (when the file is transferred successfully
      // but the date is not formatted correctly):
      // 'OKAYFAIL\npath too long'
      transferFinished.reject(
          new RecordingError(`${BINARY_PUSH_FAILURE}: ${response}`));
    } else if (textDecoder.decode(data).substring(0, 4) === 'OKAY') {
      // In case of success, the server responds to the last request with
      // 'OKAY'.
      transferFinished.resolve();
    } else {
      throw new RecordingError(`${BINARY_PUSH_UNKNOWN_RESPONSE}: ${response}`);
    }
  }

  private async sendNextDataChunk(binary: Uint8Array): Promise<boolean> {
    const endPosition = Math.min(
        this.sentByteCount + MAX_SYNC_SEND_CHUNK_SIZE, binary.byteLength);
    const chunk = await binary.slice(this.sentByteCount, endPosition);
    // The file is sent in chunks. Each chunk is prefixed with "DATA" and the
    // chunk length. This is repeated until the entire file is transferred. Each
    // chunk must not be larger than 64k.
    const chunkLength = chunk.byteLength;
    const dataMessage = new ArrayBufferBuilder();
    dataMessage.append('DATA');
    dataMessage.append(chunkLength);
    dataMessage.append(
        new Uint8Array(chunk.buffer, chunk.byteOffset, chunkLength));

    this.sentByteCount += chunkLength;
    const isDone = this.sentByteCount === binary.byteLength;

    if (isDone) {
      // When the file is transferred a sync request "DONE" is sent, together
      // with a timestamp, representing the last modified time for the file. The
      // server responds to this last request.
      dataMessage.append('DONE');
      // We send the date in seconds.
      dataMessage.append(Math.floor(Date.now() / 1000));
    }
    this.byteStream.write(new Uint8Array(dataMessage.toArrayBuffer()));
    return isDone;
  }
}
