// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

"use strict";

// Use 16x16 aligned resolution since some platforms require that.
// See https://crbug.com/1084702.
// Also, some platforms require a resolution that isn't tiny (e.g. 160) to
// use hardware acceleration.
const FRAME_WIDTH = 640;
const FRAME_HEIGHT = 480;

class TestHarness {
  finished = false;
  success = false;
  skipped = false;
  message = 'ok';
  logs = [];
  logWindow = null;

  constructor() {}

  skip(message) {
    this.skipped = true;
    this.finished = true;
    this.message = message;
    this.log('Test skipped: ' + message);
  }

  reportSuccess() {
    this.finished = true;
    this.success = true;
    this.log('Test completed');
  }

  reportFailure(error) {
    this.finished = true;
    this.success = false;
    this.message = error.toString();
    this.log(this.message);
  }

  assert(condition, msg) {
    if (!condition)
      this.reportFailure("Assertion failed: " + msg);
  }

  assert_eq(val1, val2, msg) {
    if (val1 != val2) {
      this.reportFailure(`Assertion failed: ${msg}. ${val1} != ${val2}.`);
    }
  }

  summary() {
    return this.message + "\n\n" + this.logs.join("\n");
  }

  log(msg) {
    this.logs.push(msg);
    console.log(msg);
    if (this.logWindow === null)
      this.logWindow = document.querySelector('textarea');
    if (this.logWindow)
      this.logWindow.value += msg + '\n';
  }

  run(arg) {
    main(arg).then(
        _ => {
          if (!this.finished)
            this.reportSuccess();
        },
        error => {
          if (!this.finished)
            this.reportFailure(error);
        });
  }
};
var TEST = new TestHarness();

function waitForNextFrame() {
  return new Promise((resolve, _) => {
    window.requestAnimationFrame(resolve);
  });
}

function fourColorsFrame(ctx, width, height, text) {
  const kYellow = "#FFFF00";
  const kRed = "#FF0000";
  const kBlue = "#0000FF";
  const kGreen = "#00FF00";

  ctx.fillStyle = kYellow;
  ctx.fillRect(0, 0, width / 2, height / 2);

  ctx.fillStyle = kRed;
  ctx.fillRect(width / 2, 0, width / 2, height / 2);

  ctx.fillStyle = kBlue;
  ctx.fillRect(0, height / 2, width / 2, height / 2);

  ctx.fillStyle = kGreen;
  ctx.fillRect(width / 2, height / 2, width / 2, height / 2);

  ctx.fillStyle = 'white';
  ctx.font = (height / 10) + 'px sans-serif';
  ctx.fillText(text, width / 2, height / 2);
}

function peekPixel(ctx, x, y) {
  if (ctx.readPixels) {
    let pixels = new Uint8Array(4);
    ctx.readPixels(x, ctx.drawingBufferHeight - y, 1, 1,
                   ctx.RGBA, ctx.UNSIGNED_BYTE, pixels);
    return Array.from(pixels);
  }
  if (ctx.getImageData) {
    let settings = {colorSpaceConversion: 'none'};
    return ctx.getImageData(x, y, 1, 1, settings).data;
  }
}

function compareColors(actual, expected, tolerance, msg) {
  let channel = ['R', 'G', 'B', 'A'];
  for (let i = 0; i < 4; i++) {
    if (Math.abs(actual[i] - expected[i]) > tolerance) {
      TEST.reportFailure(msg +
       ` channel: ${channel[i]} actual: ${actual[i]} expected: ${expected[i]}`);
    }
  }
}

function checkFourColorsFrame(ctx, width, height, tolerance) {
  const kYellow = [0xFF, 0xFF, 0x00, 0xFF];
  const kRed = [0xFF, 0x00, 0x00, 0xFF];
  const kBlue = [0x00, 0x00, 0xFF, 0xFF];
  const kGreen = [0x00, 0xFF, 0x00, 0xFF];

  let m = 10; // margin from the frame's edge
  compareColors(peekPixel(ctx, m, m), kYellow,
                      tolerance, 'top left corner is yellow');
  compareColors(peekPixel(ctx, width - m, m), kRed,
                      tolerance, 'top right corner is red');
  compareColors(peekPixel(ctx, m, height - m), kBlue,
                      tolerance, 'bottom left corner is blue');
  compareColors(peekPixel(ctx, width - m, height - m), kGreen,
                      tolerance, 'bottom right corner is green');
}

// Paints |count| black dots on the |ctx|, so their presence can be validated
// later. This is an analog of the most basic bar code.
function putBlackDots(ctx, width, height, count) {
  ctx.fillStyle = 'black';
  const dot_size = 10;
  const step = dot_size * 3;

  for (let i = 1; i <= count; i++) {
    let x = i * step;
    let y = step * (x / width + 1);
    x %= width;
    ctx.fillRect(x, y, dot_size, dot_size);
  }
}

// Validates that frame has |count| black dots in predefined places.
function validateBlackDots(frame, count) {
  const width = frame.displayWidth;
  const height = frame.displayHeight;
  let cnv = new OffscreenCanvas(width, height);
  var ctx = cnv.getContext('2d', { willReadFrequently : true });
  ctx.drawImage(frame, 0, 0);
  const dot_size = 10;
  const step = dot_size * 3;

  for (let i = 1; i <= count; i++) {
    let x = i * step + dot_size / 2;
    let y = step * (x / width + 1) + dot_size / 2;
    x %= width;
    let rgba = ctx.getImageData(x, y, 1, 1).data;
    const tolerance = 40;
    if (rgba[0] > tolerance || rgba[1] > tolerance || rgba[2] > tolerance) {
      // The dot is too bright to be a black dot.
      return false;
    }
  }
  return true;
}


// Base class for video frame sources.
class FrameSource {
  constructor() {}

  async getNextFrame() {
    return null;
  }

  close() {}
}

// Source of video frames coming from taking snapshots of a canvas.
class CanvasSource extends FrameSource {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
    this.canvas = new OffscreenCanvas(width, height);
    this.ctx = this.canvas.getContext('2d', {colorSpace: 'srgb'});
    this.timestamp = 0;
    this.duration = 16666;  // 1/60 s
    this.frame_index = 0;
  }

  async getNextFrame() {
    fourColorsFrame(this.ctx, this.width, this.height,
                    this.timestamp.toString());
    putBlackDots(this.ctx, this.width, this.height, this.frame_index);
    let result = new VideoFrame(this.canvas, {timestamp: this.timestamp});
    this.timestamp += this.duration;
    this.frame_index++;
    return result;
  }
}

// Source of video frames coming from MediaStreamTrack.
class StreamSource extends FrameSource {
  constructor(track) {
    super();
    this.media_processor = new MediaStreamTrackProcessor(track);
    this.reader = this.media_processor.readable.getReader();
  }

  async getNextFrame() {
    const result = await this.reader.read();
    const frame = result.value;
    return frame;
  }

  close() {
    if (this.reader)
      this.reader.cancel();
  }
}

class ArrayBufferSource extends FrameSource {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
    this.canvas = new OffscreenCanvas(width, height);
    this.ctx = this.canvas.getContext(
        '2d', {willReadFrequently: true, colorSpace: 'srgb'});
    this.timestamp = 0;
    this.duration = 16666;  // 1/60 s
    this.frame_index = 0;
  }

  async getNextFrame() {
    fourColorsFrame(
        this.ctx, this.width, this.height, this.timestamp.toString());
    putBlackDots(this.ctx, this.width, this.height, this.frame_index);
    const imageData = this.ctx.getImageData(0, 0, this.width, this.height);
    const buffer = imageData.data;
    let init = {
      format: 'RGBA',
      timestamp: this.timestamp,
      codedWidth: this.width,
      codedHeight: this.height,
      // This describes sRGB color-space used by the canvas
      colorSpace: {
        fullRange: true,
        matrix: 'rgb',
        primaries: 'bt709',
        transfer: 'iec61966-2-1'
      },
      transfer: [buffer.buffer]
    };
    this.timestamp += this.duration;
    this.frame_index++;
    return new VideoFrame(buffer, init);
  }
}

class HBDArrayBufferSource extends FrameSource {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
    this.timestamp = 0;
    this.duration = 16666;  // 1/60 s
    this.frame_index = 0;
  }

  async getNextFrame() {
    const kDepth = 10;
    const kShift = kDepth - 8;
    // 8-bit YUV colors assuming BT.709 matrix and sRGB primaries.
    const kYellow = [219, 16, 138];
    const kRed = [63, 102, 240];
    const kBlue = [32, 240, 118];
    const kGreen = [173, 42, 26];

    const width = this.width;
    const height = this.height;
    const halfW = Math.ceil(width / 2);
    const halfH = Math.ceil(height / 2);
    const qtrW = Math.ceil(width / 4);
    const qtrH = Math.ceil(height / 4);
    const data = new Uint8Array((width * height + 2 * halfW * halfH) * 2);
    const view = new DataView(data.buffer)

    let i = 0;

    // Y plane.
    for (let y = 0; y < height; ++y) {
      const colors = y < halfH ? [kYellow, kRed] : [kBlue, kGreen];
      for (let x = 0; x < width; ++x) {
        const color = x < halfW ? colors[0] : colors[1];
        // Note: Rounding is not quite accurate due to shifting rather than
        // scaling, in addition to using already rounded YUV values.
        view.setUint16(i, color[0] << kShift, true);
        i += 2;
      }
    }

    // U plane.
    for (let y = 0; y < halfH; ++y) {
      const colors = y < qtrH ? [kYellow, kRed] : [kBlue, kGreen];
      for (let x = 0; x < halfW; ++x) {
        const color = x < qtrW ? colors[0] : colors[1];
        view.setUint16(i, color[1] << kShift, true);
        i += 2;
      }
    }

    // V plane.
    for (let y = 0; y < halfH; ++y) {
      const colors = y < qtrH ? [kYellow, kRed] : [kBlue, kGreen];
      for (let x = 0; x < halfW; ++x) {
        const color = x < qtrW ? colors[0] : colors[1];
        view.setUint16(i, color[2] << kShift, true);
        i += 2;
      }
    }

    const init = {
      format: `I420P${kDepth}`,
      timestamp: this.timestamp,
      codedWidth: width,
      codedHeight: height,
      // sRGB with BT.709 YUV matrix.
      colorSpace: {
        matrix: 'bt709',
        primaries: 'bt709',
        transfer: 'iec61966-2-1',
        fullRange: false,
      },
      transfer: [data.buffer]
    };
    this.timestamp += this.duration;
    this.frame_index++;
    return new VideoFrame(data, init);
  }
}

class HDRCanvasSource extends FrameSource {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
    this.timestamp = 0;
    this.duration = 16666;  // 1/60 s
    this.frame_index = 0;
  }

  async getNextFrame() {
    const canvas2D = document.createElement('canvas');
    canvas2D.id = 'hdr-2d-canvas';
    canvas2D.width = this.width;
    canvas2D.height = this.height;
    canvas2D.configureHighDynamicRange({ mode: "extended" });

    const ctx2D = canvas2D.getContext('2d', {
      colorSpace: 'srgb-linear',
      colorType: 'float16',
      willReadFrequently: true,
    });

    const width = this.width;
    const height = this.height;
    const halfWidth = width / 2;
    const halfHeight = height / 2;

    // Clear canvas
    ctx2D.clearRect(0, 0, width, height);

    // Create HDR colors with higher intensity values for true HDR
    const hdrIntensity = 5; // HDR multiplier

    // Top-left: Blue (HDR)
    ctx2D.fillStyle = `color(srgb-linear 0 0 ${hdrIntensity})`;
    ctx2D.fillRect(0, 0, halfWidth, halfHeight);

    // Top-right: Yellow (HDR)
    ctx2D.fillStyle = `color(srgb-linear ${hdrIntensity} ${hdrIntensity} 0)`;
    ctx2D.fillRect(halfWidth, 0, halfWidth, halfHeight);

    // Bottom-left: Green (HDR)
    ctx2D.fillStyle = `color(srgb-linear 0 ${hdrIntensity} 0)`;
    ctx2D.fillRect(0, halfHeight, halfWidth, halfHeight);

    // Bottom-right: Red (HDR)
    ctx2D.fillStyle = `color(srgb-linear ${hdrIntensity} 0 0)`;
    ctx2D.fillRect(halfWidth, halfHeight, halfWidth, halfHeight);

    // Center white rectangle (Super bright HDR white)
    const centerW = width * 0.05;
    const centerH = height * 0.05;
    const centerX = (width - centerW) / 2;
    const centerY = (height - centerH) / 2;

    const white = 10.0; // Very bright HDR white
    ctx2D.fillStyle = `color(srgb-linear ${white} ${white} ${white})`;
    ctx2D.fillRect(centerX, centerY, centerW, centerH);

    const init = {
      timestamp: this.timestamp,
    };
    this.timestamp += this.duration;
    this.frame_index++;
    return new VideoFrame(canvas2D, init);
  }
}

// Source of video frames coming from either hardware of software decoder.
class DecoderSource extends FrameSource {
  constructor(decoderConfig, chunks) {
    super();
    this.decoderConfig = decoderConfig;
    this.frames = [];
    this.error = null;
    this.decoder = new VideoDecoder(
        {error: this.onError.bind(this), output: this.onFrame.bind(this)});
    this.decoder.configure(this.decoderConfig);
    while (chunks.length != 0) {
      this.decoder.decode(chunks.shift());
    }
    this.decoder.flush().catch((e) => {});
  }

  onError(error) {
    TEST.log(error);
    this.error = error;
    if (this.next) {
      this.next.reject(error);
      this.next = null;
    }
  }

  onFrame(frame) {
    if (this.next) {
      this.next.resolve(frame);
      this.next = null;
    } else {
      this.frames.push(frame);
    }
  }

  async getNextFrame() {
    if (this.next) {
      return this.next.promise;
    }

    if (this.frames.length > 0) {
      return this.frames.shift();
    }

    if (this.error) {
      throw this.error;
    }

    let next = {};
    this.next = next;
    this.next.promise = new Promise((resolve, reject) => {
      next.resolve = resolve;
      next.reject = reject;
    });

    return next.promise;
  }

  close() {
    if (this.decoder) {
      this.decoder.close();
      this.decoder = null;
    }
  }
}

function createCanvasCaptureSource(width, height) {
  let canvas = document.createElement('canvas');
  canvas.id = 'canvas-for-capture';
  canvas.width = width;
  canvas.height = height;
  document.body.appendChild(canvas);

  let ctx = canvas.getContext('2d');
  let drawOneFrame = function(time) {
    fourColorsFrame(ctx, width, height, time.toString());
    window.requestAnimationFrame(drawOneFrame);
  };
  window.requestAnimationFrame(drawOneFrame);

  const stream = canvas.captureStream(60);
  const track = stream.getVideoTracks()[0];
  return new StreamSource(track);
}

async function prepareDecoderSource(
    frames_to_encode, width, height, codec, acceleration) {
  if (!acceleration)
    acceleration = 'no-preference';
  const encoder_config = {
    codec: codec,
    width: width,
    height: height,
    bitrate: 10000000,
    framerate: 24
  };

  if (codec.startsWith('avc1')) {
    encoder_config.avc = {format: 'annexb'};
  } else if (codec.startsWith('hvc1')) {
    encoder_config.hevc = {format: 'annexb'};
  }

  let decoder_config = {
    codec: codec,
    codedWidth: width,
    codedHeight: height,
    visibleRegion: {left: 0, top: 0, width: width, height: height},
    hardwareAcceleration: acceleration
  };

  try {
    let support = await VideoDecoder.isConfigSupported(decoder_config);
    if (!support.supported)
      return null;
  } catch (e) {
    return null;
  }

  let chunks = [];
  let errors = 0;
  const init = {
    output(chunk, metadata) {
      let config = metadata.decoderConfig;
      if (config) {
        decoder_config = config;
        decoder_config.hardwareAcceleration = acceleration;
      }
      chunks.push(chunk);
    },
    error(e) {
      errors++;
      TEST.log(e);
    }
  };

  let encoder = new VideoEncoder(init);
  encoder.configure(encoder_config);
  let innerSource = new ArrayBufferSource(width, height);

  for (let i = 0; i < frames_to_encode; i++) {
    let frame = await innerSource.getNextFrame();
    encoder.encode(frame, {keyFrame: false});
    frame.close();
  }
  try {
    await encoder.flush();
    encoder.close();
    innerSource.close();
  } catch (e) {
    errors++;
    TEST.log(e);
  }

  if (errors > 0)
    return null;

  return new DecoderSource(decoder_config, chunks);
}

async function createFrameSource(type, width, height) {
  switch (type) {
    case 'camera': {
      let constraints = {audio: false, video: {width: width, height: height}};
      let stream =
          await window.navigator.mediaDevices.getUserMedia(constraints);
      var track = stream.getTracks()[0];
      return new StreamSource(track);
    }
    case 'capture': {
      return createCanvasCaptureSource(width, height);
    }
    case 'offscreen': {
      return new CanvasSource(width, height);
    }
    case 'hw_decoder': {
      // Trying to find any hardware decoder supported by the platform.
      let src = await prepareDecoderSource(
          40, width, height, 'avc1.42001E', 'prefer-hardware');
      if (!src)
        src = await prepareDecoderSource(
            40, width, height, 'hvc1.1.6.L123.00', 'prefer-hardware');
      if (!src)
        src = await prepareDecoderSource(
            40, width, height, 'vp8', 'prefer-hardware');
      if (!src) {
        src = await prepareDecoderSource(
            40, width, height, 'vp09.00.10.08', 'prefer-hardware');
      }
      if (!src) {
        TEST.log('Can\'t find a supported hardware decoder.');
      }
      return src;
    }
    case 'sw_decoder': {
      return await prepareDecoderSource(
          40, width, height, 'vp8', 'prefer-software');
    }
    case 'arraybuffer': {
      return new ArrayBufferSource(width, height);
    }
    case 'hbd_arraybuffer': {
      return new HBDArrayBufferSource(width, height);
    }
    case 'hdr_canvas': {
      return new HDRCanvasSource(width, height);
    }
  }
}

function addManualTestButton(configs) {
  document.addEventListener('DOMContentLoaded', _ => {
    configs.forEach(config => {
      const btn = document.createElement('button');
      const label = document.createTextNode(
          'Run test with config: ' + JSON.stringify(config));
      btn.onclick = function() {
        main(config);
      };
      btn.appendChild(label);
      btn.style.margin = '5px';
      document.body.appendChild(btn);
    });
  }, true);
}

function readProfileFromAvcExtraData(view) {
  if (view.byteLength < 6) {
    // Too short to be a proper AVCDecoderConfigurationRecord
    return null;
  }
  const version = view.getUint8(0);
  if (version != 1) {
    return null;
  }

  const profile = view.getUint8(1);
  return profile;
}
