import { Lengthed } from '@hazae41/lengthed';
import { Ownable } from '../../libs/ownable/index.js';

declare namespace Abstract {
    abstract class Memory<N extends number = number> {
        abstract [Symbol.dispose](): void;
        abstract readonly inner: unknown;
        abstract readonly bytes: Uint8Array & Lengthed<N>;
    }
    namespace Memory {
        interface Static {
            fromOrThrow<N extends number>(memory: Memory<N>): Ownable<Memory<N>>;
            importOrThrow<N extends number>(bytes: Uint8Array & Lengthed<N>): Memory<N>;
        }
    }
    abstract class ChaCha20Cipher implements Disposable {
        abstract [Symbol.dispose](): void;
        abstract applyOrThrow(message: Memory): void;
    }
    namespace ChaCha20Cipher {
        interface Static {
            importOrThrow(key: Memory<32>, nonce: Memory<12>): ChaCha20Cipher;
        }
    }
    abstract class ChaCha20Poly1305Cipher implements Disposable {
        abstract [Symbol.dispose](): void;
        abstract encryptOrThrow(message: Memory, nonce: Memory<12>): Memory;
        abstract decryptOrThrow(message: Memory, nonce: Memory<12>): Memory;
    }
    namespace ChaCha20Poly1305Cipher {
        interface Static {
            importOrThrow(key: Memory<32>): ChaCha20Poly1305Cipher;
        }
    }
}

export { Abstract };
