// This file has been generated by structbuf. Do not modify it!
import * as base from '~/common/network/structbuf/base.js';
import type * as types from '~/common/types.js';
import * as utils from '../utils.js';

/**
 * ## Crypto
 *
 * Contains encrypted data, prefixed with a 24 byte nonce.
 *
 * Note: This can be used for all ciphers using a 24 byte nonce, e.g.
 * XSalsa20-Poly1305 and ChaCha20-Poly1305.
 */
export interface EncryptedDataWithNonceAheadLike {
    /**
     * Nonce used for encrypting the data.
     */
    readonly nonce: Uint8Array;

    /**
     * The encrypted data.
     */
    readonly data: Uint8Array;
}

/**
 * Encodable of {@link EncryptedDataWithNonceAheadLike}.
 */
interface EncryptedDataWithNonceAheadEncodable_ {
    /**
     * 'nonce' field value or encoder. See {@link EncryptedDataWithNonceAheadLike#nonce} for
     * the field's description.
     */
    readonly nonce: Uint8Array | types.ByteLengthEncoder;

    /**
     * 'data' field value or encoder. See {@link EncryptedDataWithNonceAheadLike#data} for
     * the field's description.
     */
    readonly data: Uint8Array | types.ByteLengthEncoder;
}

/**
 * New-type for EncryptedDataWithNonceAheadEncodable.
 */
export type EncryptedDataWithNonceAheadEncodable = types.WeakOpaque<
    EncryptedDataWithNonceAheadEncodable_,
    {readonly EncryptedDataWithNonceAheadEncodable: unique symbol}
>;

/** @inheritdoc */
export class EncryptedDataWithNonceAhead
    extends base.Struct
    implements EncryptedDataWithNonceAheadLike
{
    private readonly _array: Uint8Array;

    /**
     * Create a EncryptedDataWithNonceAhead from an array for accessing properties.
     *
     * Note: When accessing, attributes will be decoded on-the-fly which may be expensive.
     */
    private constructor(array: Uint8Array) {
        super();
        this._array = array;
    }

    /**
     * Decode a encrypted-data-with-nonce-ahead struct from an array.
     *
     * @param array Array to decode from.
     * @returns EncryptedDataWithNonceAhead instance.
     */
    public static decode(array: Uint8Array): EncryptedDataWithNonceAhead {
        return new EncryptedDataWithNonceAhead(array);
    }

    /**
     * Encode a encrypted-data-with-nonce-ahead struct into an array.
     *
     * @param struct EncryptedDataWithNonceAheadEncodable to encode.
     * @param array Array to encode into.
     * @returns A subarray of array containing the encoded struct.
     */
    public static encode(
        struct: types.EncoderPick<EncryptedDataWithNonceAheadEncodable, 'encode'>,
        array: Uint8Array,
    ): Uint8Array {
        let offset = 24;

        // Encode `nonce`
        utils.encodeBytes(struct.nonce, array, 0);

        // Encode `data`
        offset += utils.encodeBytes(struct.data, array, offset);

        return array.subarray(0, offset);
    }

    /**
     * Get the amount of bytes that would be written when encoding a encrypted-data-with-nonce-ahead struct into an
     * array.
     *
     * @param struct EncryptedDataWithNonceAheadEncodable to encode.
     * @returns The amount of bytes that would be required to encode the struct.
     */
    public static byteLength(
        struct: types.EncoderPick<EncryptedDataWithNonceAheadEncodable, 'byteLength'>,
    ): types.u53 {
        let offset = 24;
        offset += utils.getByteLength(struct.data);
        return offset;
    }

    /**
     * 'nonce' field accessor. See {@link EncryptedDataWithNonceAheadLike#nonce} for the
     * field's description.
     */
    public get nonce(): Uint8Array {
        const offset = 0;
        return this._array.subarray(offset, offset + 24);
    }

    /**
     * 'data' field accessor. See {@link EncryptedDataWithNonceAheadLike#data} for the
     * field's description.
     */
    public get data(): Uint8Array {
        return this._array.subarray(24);
    }

    /**
     * Create a snapshot of EncryptedDataWithNonceAheadLike.
     *
     * Note: This is **not** a deep-copy, so byte arrays will still be views of the underlying
     *       buffer.
     *
     * @returns EncryptedDataWithNonceAheadLike snapshot.
     */
    public snapshot(): EncryptedDataWithNonceAheadLike {
        return {
            nonce: this.nonce,
            data: this.data,
        };
    }

    /**
     * Create a clone of EncryptedDataWithNonceAheadLike.
     *
     * Note: This is a deep-copy that will copy the underlying buffer.
     *
     * @returns EncryptedDataWithNonceAheadLike clone.
     */
    public clone(): EncryptedDataWithNonceAhead {
        const array = new Uint8Array(this._array.byteLength);
        array.set(this._array);
        return new EncryptedDataWithNonceAhead(array);
    }
}
