/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { Bytes, UnexpectedDataError } from "#general";
import { Schema } from "./Schema.js";
const BASE38_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-.";
class Base38Schema extends Schema {
  encodeInternal(data) {
    const bytes = Bytes.of(data);
    const length = bytes.length;
    let offset = 0;
    const result = new Array();
    while (offset < length) {
      const remaining = length - offset;
      if (remaining > 2) {
        result.push(this.encodeBase38(bytes[offset++] | bytes[offset++] << 8 | bytes[offset++] << 16, 5));
      } else if (remaining == 2) {
        result.push(this.encodeBase38(bytes[offset++] | bytes[offset++] << 8, 4));
        break;
      } else {
        result.push(this.encodeBase38(bytes[offset++], 2));
        break;
      }
    }
    return result.join("");
  }
  encodeBase38(value, charCount) {
    let result = "";
    for (let i = 0; i < charCount; i++) {
      const remainder = value % 38;
      result += BASE38_ALPHABET[remainder];
      value = (value - remainder) / 38;
    }
    return result;
  }
  decodeInternal(encoded) {
    const encodedLength = encoded.length;
    const remainderEncodedLength = encodedLength % 5;
    let decodeLength = (encodedLength - remainderEncodedLength) / 5 * 3;
    switch (remainderEncodedLength) {
      case 4:
        decodeLength += 2;
        break;
      case 2:
        decodeLength += 1;
        break;
      default:
        throw new UnexpectedDataError(`Invalid base38 encoded string length: ${encodedLength}`);
    }
    const result = new Uint8Array(decodeLength);
    let decodedOffset = 0;
    let encodedOffset = 0;
    while (encodedOffset < encodedLength) {
      const remaining = encodedLength - encodedOffset;
      if (remaining > 5) {
        const value = this.decodeBase38(encoded, encodedOffset, 5);
        result[decodedOffset++] = value & 255;
        result[decodedOffset++] = value >> 8 & 255;
        result[decodedOffset++] = value >> 16 & 255;
        encodedOffset += 5;
      } else if (remaining === 4) {
        const value = this.decodeBase38(encoded, encodedOffset, 4);
        result[decodedOffset++] = value & 255;
        result[decodedOffset++] = value >> 8 & 255;
        break;
      } else {
        const value = this.decodeBase38(encoded, encodedOffset, 2);
        result[decodedOffset++] = value & 255;
        break;
      }
    }
    return result;
  }
  decodeBase38(encoded, offset, charCount) {
    let result = 0;
    for (let i = charCount - 1; i >= 0; i--) {
      const char = encoded[offset + i];
      const code = BASE38_ALPHABET.indexOf(char);
      if (code === -1) throw new UnexpectedDataError(`Unexpected character ${char} at ${offset + i}`);
      result = result * 38 + code;
    }
    return result;
  }
}
const Base38 = new Base38Schema();
export {
  Base38
};
//# sourceMappingURL=Base38Schema.js.map
