// Copyright 2021 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.

/** Low-level HDLC protocol features. */
import {Buffer} from 'buffer';
import {crc32} from 'crc';

/** Special flag character for delimiting HDLC frames. */
export const FLAG = 0x7e;

/** Special character for escaping other special characters in a frame. */
export const ESCAPE = 0x7d;

/** Characters allowed after a 0x7d escape character. */
export const VALID_ESCAPED_BYTES = [0x5D, 0x5E];

/** Frame control for unnumbered information */
export const UI_FRAME_CONTROL = frameControl(0x00);

/** Maximum allowed HDLC address (uint64_t in C++). */
const MAX_ADDRESS = 2 ** 64 - 1;

/**
 * Bitwise OR operation on numbers up to MAX_ADDRESS size.
 * Native bitwise operators only support signed Int32.
 */
function bitwiseOr(x: number, y: number) {
  const highMask = 0x80000000;
  const lowMask = 0x7fffffff;
  const highX = ~~(x / highMask);
  const highY = ~~(y / highMask);
  const lowX = x & lowMask;
  const lowY = y & lowMask;
  const highOr = highX | highY;
  const lowOr = lowX | lowY;
  return highOr * highMask + lowOr;
}

/** Calculates the CRC32 of |data| */
export function frameCheckSequence(data: Uint8Array): Uint8Array {
  const crc = crc32(Buffer.from(data.buffer, data.byteOffset, data.byteLength));
  const arr = new ArrayBuffer(4);
  const view = new DataView(arr);
  view.setUint32(0, crc, true);  // litteEndian = true
  return new Uint8Array(arr);
}

/** Escapes or unescapes a byte, which should have been preceeded by 0x7d */
export function escape(byte: number): number {
  return byte ^ 0x20;
}

/** Encodes an HDLC address as a one-terminated LSB varint. */
export function encodeAddress(address: number): Uint8Array {
  const byteList = [];
  while (true) {
    byteList.push((address & 0x7f) << 1);
    address >>= 7;
    if (address === 0) {
      break;
    }
  }

  let result = Uint8Array.from(byteList);
  result[result.length - 1] |= 0x1;
  return result;
}

/** Decodes an HDLC address from a frame, returning it and its size. */
export function decodeAddress(frame: Uint8Array): [number, number] {
  let result = 0;
  let length = 0;

  while (length < frame.length) {
    const byte = frame[length];
    const shift = (byte >> 1) * (2 ** (length * 7));
    result = bitwiseOr(result, shift);
    length += 1;

    if (shift > MAX_ADDRESS || result > MAX_ADDRESS) {
      return [-1, 0];
    }
    if ((byte & 0x1) === 0x1) {
      break;
    }
  }
  return [result, length];
}

function frameControl(frameType: number): Uint8Array {
  return Uint8Array.from([0x03 | frameType]);
}
