/**
 * ShareData Value Object
 *
 * Encrypted share data with AES-GCM parameters.
 */

export class ShareData {
  private readonly _encryptedData: Buffer;
  private readonly _iv: Buffer;           // Initialization vector
  private readonly _authTag: Buffer;      // Authentication tag (AES-GCM)

  private constructor(encryptedData: Buffer, iv: Buffer, authTag: Buffer) {
    this._encryptedData = encryptedData;
    this._iv = iv;
    this._authTag = authTag;
  }

  get encryptedData(): Buffer {
    return this._encryptedData;
  }

  get iv(): Buffer {
    return this._iv;
  }

  get authTag(): Buffer {
    return this._authTag;
  }

  static create(encryptedData: Buffer, iv: Buffer, authTag: Buffer): ShareData {
    if (!encryptedData || encryptedData.length === 0) {
      throw new Error('Encrypted data cannot be empty');
    }
    if (!iv || iv.length !== 12) {
      throw new Error('IV must be 12 bytes for AES-GCM');
    }
    if (!authTag || authTag.length !== 16) {
      throw new Error('AuthTag must be 16 bytes for AES-GCM');
    }
    return new ShareData(encryptedData, iv, authTag);
  }

  toJSON(): { data: string; iv: string; authTag: string } {
    return {
      data: this._encryptedData.toString('base64'),
      iv: this._iv.toString('base64'),
      authTag: this._authTag.toString('base64'),
    };
  }

  static fromJSON(json: { data: string; iv: string; authTag: string }): ShareData {
    return new ShareData(
      Buffer.from(json.data, 'base64'),
      Buffer.from(json.iv, 'base64'),
      Buffer.from(json.authTag, 'base64'),
    );
  }

  toString(): string {
    return JSON.stringify(this.toJSON());
  }
}
