// Copyright 2022 The Pigweed Authors
//
// 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
//
//     https://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.

/* eslint-env browser */
import { last, take } from 'rxjs/operators';

import { SerialMock } from './serial_mock';
import { WebSerialTransport, DeviceLockedError } from './web_serial_transport';
import type { Serial } from 'pigweedjs/types/serial';

describe('WebSerialTransport', () => {
  let serialMock: SerialMock;
  beforeEach(() => {
    serialMock = new SerialMock();
  });

  it('is disconnected before connecting', () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    expect(transport.connected.getValue()).toBe(false);
  });

  it('reports that it has connected', async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();
    expect(serialMock.serialPort.open).toHaveBeenCalled();
    expect(transport.connected.getValue()).toBe(true);
  });

  it('emits chunks as they arrive from the device', async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();
    const data = new Uint8Array([1, 2, 3]);
    const emitted = transport.chunks.pipe(take(1)).toPromise();
    serialMock.dataFromDevice(data);

    expect(await emitted).toEqual(data);
    expect(transport.connected.getValue()).toBe(true);
    expect(serialMock.serialPort.readable.locked).toBe(true);
    expect(serialMock.serialPort.writable.locked).toBe(true);
  });

  it('is disconnected when it reaches the final chunk', async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();
    const disconnectPromise = transport.connected
      .pipe(take(2), last())
      .toPromise();
    serialMock.closeFromDevice();

    expect(await disconnectPromise).toBe(false);
  });

  it('waits for the writer to be ready', async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();
    const data = new Uint8Array([1, 2, 3]);

    const dataToDevice = serialMock.dataToDevice.pipe(take(1)).toPromise();

    let writtenData: Uint8Array | undefined = undefined;
    dataToDevice.then((data) => {
      writtenData = data;
    });

    const sendPromise = transport.sendChunk(data);
    expect(writtenData).toBeUndefined();
    await sendPromise;
    expect(writtenData).toBeDefined();
  });

  it('sends chunks to the device', async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();
    const data = new Uint8Array([1, 2, 3]);

    const dataToDevice = serialMock.dataToDevice.pipe(take(1)).toPromise();

    await transport.sendChunk(data);
    expect(await dataToDevice).toEqual(data);
  });

  it('throws an error on failing to connect', async () => {
    const connectError = new Error('Example connection error');
    const spy = jest.spyOn(serialMock, 'requestPort').mockImplementation(() => {
      throw connectError;
    });
    const transport = new WebSerialTransport(serialMock as Serial);
    await expect(transport.connect()).rejects.toThrow(connectError.message);
  });

  it("emits connection errors in the 'errors' observable", async () => {
    const transport = new WebSerialTransport(serialMock as Serial);
    await transport.connect();

    const reportedErrorPromise = transport.errors.pipe(take(1)).toPromise();
    serialMock.serialPort.errorFromDevice(new DeviceLockedError());

    expect(await reportedErrorPromise).toEqual(new DeviceLockedError());
  });
});
