import{ok,err}from"../_deps/shared/index.js";export class ValidationPlugin{name="validation";version="1.0.0";description="Validates payloads and envelopes before processing";priority=5;options;validationErrors=[];constructor(e={}){this.options={maxPayloadSize:e.maxPayloadSize??10485760,maxEnvelopeSize:e.maxEnvelopeSize??15728640,allowedScopes:e.allowedScopes??[],customRules:e.customRules??[],strictMode:e.strictMode??!1,validateSchema:e.validateSchema??!1}}onInit(){return ok(void 0)}onDestroy(){return this.validationErrors=[],ok(void 0)}onSend(e,r){const t=this.validatePayloadSize(e);if(!1===t.ok)return this.recordError("payload_size",t.error),err(t.error);if(r.scope){const e=this.validateScope(r.scope);if(!1===e.ok)return this.recordError("scope",e.error),err(e.error)}const o=this.validatePayloadStructure(e);if(!1===o.ok)return this.recordError("payload_structure",o.error),err(o.error);for(const t of this.options.customRules)if(!t.appliesTo||t.appliesTo.includes("send")){const o=t.validate(e,r);if(o)return this.recordError(t.name,o),err(`VALIDATION_FAILED:${t.name}:${o}`)}return ok({payload:e})}onReceive(e,r){const t=this.validateEnvelopeSize(e);if(!1===t.ok)return this.recordError("envelope_size",t.error),err(t.error);const o=this.validateEnvelopeStructure(e);if(!1===o.ok)return this.recordError("envelope_structure",o.error),err(o.error);for(const t of this.options.customRules)if(!t.appliesTo||t.appliesTo.includes("receive")){const o=t.validate(e,r);if(o)return this.recordError(t.name,o),err(`VALIDATION_FAILED:${t.name}:${o}`)}return ok({payload:e})}onEncrypt(e,r){if(0===e.length)return this.recordError("plaintext_empty","Plaintext cannot be empty"),err("VALIDATION_FAILED:PLAINTEXT_EMPTY");if(e.length>this.options.maxPayloadSize)return this.recordError("plaintext_size",`Plaintext exceeds max size: ${e.length} bytes`),err(`VALIDATION_FAILED:PLAINTEXT_TOO_LARGE:${e.length}`);for(const t of this.options.customRules)if(!t.appliesTo||t.appliesTo.includes("encrypt")){const o=t.validate(e,r);if(o)return this.recordError(t.name,o),err(`VALIDATION_FAILED:${t.name}:${o}`)}return ok({payload:e})}onDecrypt(e,r){if(0===e.length)return this.recordError("plaintext_empty","Decrypted plaintext is empty"),err("VALIDATION_FAILED:DECRYPTED_EMPTY");for(const t of this.options.customRules)if(!t.appliesTo||t.appliesTo.includes("decrypt")){const o=t.validate(e,r);if(o)return this.recordError(t.name,o),err(`VALIDATION_FAILED:${t.name}:${o}`)}return ok({payload:e})}getValidationErrors(){return[...this.validationErrors]}clearErrors(){this.validationErrors=[]}addRule(e){this.options.customRules.push(e)}removeRule(e){const r=this.options.customRules.findIndex(r=>r.name===e);return-1!==r&&(this.options.customRules.splice(r,1),!0)}validatePayloadSize(e){const r=this.estimateSize(e);return r>this.options.maxPayloadSize?err(`VALIDATION_FAILED:PAYLOAD_TOO_LARGE:${r}>${this.options.maxPayloadSize}`):ok(void 0)}validateEnvelopeSize(e){const r=this.estimateSize(e);return r>this.options.maxEnvelopeSize?err(`VALIDATION_FAILED:ENVELOPE_TOO_LARGE:${r}>${this.options.maxEnvelopeSize}`):ok(void 0)}validateScope(e){return this.options.allowedScopes.length>0&&!this.options.allowedScopes.includes(e)?err(`VALIDATION_FAILED:SCOPE_NOT_ALLOWED:${e}`):ok(void 0)}validatePayloadStructure(e){if(null==e)return err("VALIDATION_FAILED:PAYLOAD_NULL_OR_UNDEFINED");try{JSON.stringify(e)}catch(e){return err(`VALIDATION_FAILED:PAYLOAD_NOT_SERIALIZABLE:${String(e)}`)}return ok(void 0)}validateEnvelopeStructure(e){return"v"in e||"version"in e?e.sender?e.recipient?"payload"in e||"ciphertext"in e?ok(void 0):err("VALIDATION_FAILED:ENVELOPE_MISSING_CIPHERTEXT"):err("VALIDATION_FAILED:ENVELOPE_MISSING_RECIPIENT"):err("VALIDATION_FAILED:ENVELOPE_MISSING_SENDER"):err("VALIDATION_FAILED:ENVELOPE_MISSING_VERSION")}estimateSize(e){if(e instanceof Uint8Array)return e.length;try{return JSON.stringify(e).length}catch{return 0}}recordError(e,r){this.validationErrors.push({timestamp:Date.now(),rule:e,error:r}),this.validationErrors.length>1e3&&this.validationErrors.shift()}}export function createValidationPlugin(e){return new ValidationPlugin(e)}export const CommonRules={requireFields:e=>({name:"require_fields",appliesTo:["send"],validate:r=>{if("object"!=typeof r||null===r)return"Payload must be an object";const t=r,o=e.filter(e=>!(e in t));return o.length>0?`Missing required fields: ${o.join(", ")}`:null}}),validateDIDFormat:()=>({name:"did_format",appliesTo:["send","receive"],validate:(e,r)=>r.recipient&&!r.recipient.startsWith("did:")?`Invalid DID format: ${r.recipient}`:null}),validateTimestamp:(e=3e5)=>({name:"timestamp_freshness",appliesTo:["receive"],validate:(r,t)=>{const o=Date.now()-t.timestamp;return o>e?`Timestamp too old: ${o}ms > ${e}ms`:null}})};