#!/usr/bin/env node
import {a}from'./chunk-QT2LKB3P.js';import'./chunk-5TAVYPOV.js';import*as y from'path';import*as h from'fs';import p from'chalk';var R=null;function G(e){R=e;}function k(){return R}async function O(e,s,t){let n=t||k();if(!n)return {passed:false,results:[],errors:["No gate client configured"]};let o=[],r=[];for(let i of s)try{let c=await n.check(e,i.entity),u=c.passed===i.expected;if(i.expectedPrizes&&c.passed){let a=c.triggeredPrizes.map(l=>l.id),f=i.expectedPrizes.filter(l=>!a.includes(l));f.length>0&&r.push(`Test "${i.name}": Expected prizes not triggered: ${f.join(", ")}`);}o.push({testCase:i,result:c,passed:u}),u||r.push(`Test "${i.name}": Expected ${i.expected?"pass":"fail"}, got ${c.passed?"pass":"fail"}`);}catch(c){r.push(`Test "${i.name}": ${c.message}`),o.push({testCase:i,result:{gate:{id:e,locks:[],prizes:[]},passed:false,lockResults:[],triggeredPrizes:[],timestamp:Date.now()},passed:false});}return {passed:r.length===0,results:o,errors:r}}async function T(e,s={}){let{outputDir:t="tests/gates",framework:n="jest",includeFlows:o=true}=s,r=await a(e),i=[],c=y.resolve(t);h.existsSync(c)||h.mkdirSync(c,{recursive:true});for(let u of r.gates){let a=N(u,n),f=`${u.id.replace(/[^a-z0-9]/gi,"-")}.test.ts`,l=y.join(c,f);h.writeFileSync(l,a,"utf8"),i.push(l);}if(o&&r.flows.length>0){let u=y.join(c,"..","flows");h.existsSync(u)||h.mkdirSync(u,{recursive:true});for(let a of r.flows){let f=z(a,r.gates,n),l=`${a.id.replace(/[^a-z0-9]/gi,"-")}.test.ts`,d=y.join(u,l);h.writeFileSync(d,f,"utf8"),i.push(d);}}return i}function N(e,s){let t=s==="mocha"||s==="vitest"?"it":"test",n=e.id,o=e.description||n,r=e.locks.map(i=>{let c=i.keys.map((u,a)=>`    ${t}('should check key: ${u.description||`Key ${a+1}`}', async () => {
      const entity = {
        // TODO: Add entity properties needed for this key
        // Key expression: ${u.expression}
      };

      const result = await checkGateway('${n}', entity);
      // TODO: Assert expected result
      expect(result.passed).toBeDefined();
    });`);return `  describe('Lock: ${i.description||i.id}', () => {
${c.join(`

`)}
  });`});return `/**
 * Generated test file for gate: ${o}
 * Gate ID: ${n}
 * 
 * TODO: Fill in entity mock data and expected results
 */

import { checkGateway, validateGateway } from '@a-company/portal-manager';
import { createGate, setGateClient } from '@a-company/portal-sdk';
import { parseGateConfig } from '@a-company/portal-core';

${s==="vitest"?"import { describe, it, expect, beforeAll } from 'vitest';":s==="mocha"?"import { describe, it } from 'mocha';":"import { describe, test as it, expect, beforeAll } from '@jest/globals';"}

describe('Gate: ${o}', () => {
  beforeAll(async () => {
    // Load gate configuration
    const config = await parseGateConfig('./portal.yaml');
    const client = createGate(config);
    setGateClient(client);
  });

${r.join(`

`)}

  ${t}('should trigger prizes when gate passes', async () => {
    const entity = {
      // TODO: Add entity that passes all locks
    };

    const result = await checkGateway('${n}', entity);
    
    if (result.passed) {
      expect(result.triggeredPrizes.length).toBeGreaterThan(0);
      // TODO: Assert specific prizes
      ${e.prizes.map(i=>`// expect(result.triggeredPrizes).toContainEqual(expect.objectContaining({ id: '${i.id}' }));`).join(`
      `)}
    }
  });
});
`}function z(e,s,t){let n=t==="mocha"||t==="vitest"?"it":"test",o=e.description||e.id,r=e.gates.map((i,c)=>`    ${n}('should pass gate ${c+1}: ${i}', async () => {
      const entity = {
        // TODO: Add entity properties
      };

      const result = await checkGateway('${i}', entity);
      expect(result.passed).toBe(true);
    });`);return `/**
 * Generated test file for flow: ${o}
 * Flow ID: ${e.id}
 * 
 * TODO: Fill in entity mock data for each gate in the flow
 */

import { checkGateway } from '@a-company/portal-manager';
import { createGate, setGateClient } from '@a-company/portal-sdk';
import { parseGateConfig } from '@a-company/portal-core';

${t==="vitest"?"import { describe, it, expect, beforeAll } from 'vitest';":t==="mocha"?"import { describe, it } from 'mocha';":"import { describe, test as it, expect, beforeAll } from '@jest/globals';"}

describe('Flow: ${o}', () => {
  beforeAll(async () => {
    const config = await parseGateConfig('./portal.yaml');
    const client = createGate(config);
    setGateClient(client);
  });

  ${n}('should complete entire flow', async () => {
    const entity = {
      // TODO: Add entity that passes all gates in flow
    };

${r.join(`

`)}
  });
});
`}async function x(e){let{rootDir:s,patterns:t=["**/*.tsx","**/*.jsx"]}=e,n=[],o=new Set;function r(i){try{let c=h.readdirSync(i,{withFileTypes:!0});for(let u of c){let a=y.join(i,u.name);if(!(u.name==="node_modules"||u.name===".git"||u.name==="dist"||u.name==="build")){if(u.isDirectory())r(a);else if(u.isFile()&&t.some(l=>{if(l.includes("**")){let d=l.split(".").pop();return a.endsWith(`.${d}`)}return a.endsWith(l)})&&!o.has(a)){o.add(a);let l=j(a);l&&n.push(l);}}}}catch{}}return r(s),n}function j(e){try{let s=h.readFileSync(e,"utf8"),t=y.basename(e,y.extname(e)),n=[/@Gate\(['"]([^'"]+)['"]\)/g,/@Gateway\(['"]([^'"]+)['"]\)/g,/GateGuard\(['"]([^'"]+)['"]\)/g,/checkGateway\(['"]([^'"]+)['"]/g,/gate:\s*['"]([^'"]+)['"]/g],o=new Set,r=[];for(let c of n){let u;for(;(u=c.exec(s))!==null;){let a=u[1];a&&a.startsWith("^")&&o.add(a);}}let i=s.includes("checkGateway")||s.includes("GateGuard")||s.includes("Gateway")||s.includes("useGate");return o.size>0&&!i&&r.push(...Array.from(o)),{filePath:e,componentName:t,requiredGates:Array.from(o),missingChecks:r}}catch{return null}}function P(e){let s=[];s.push(`# Component Access Report
`),s.push(`Generated: ${new Date().toISOString()}
`),s.push(`Total Components: ${e.length}
`);let t=e.filter(n=>n.missingChecks.length>0);if(t.length>0){s.push(`
## Components Missing Gate Checks (${t.length})
`);for(let n of t)s.push(`### ${n.componentName}`),s.push(`File: ${n.filePath}`),s.push(`Missing checks for gates: ${n.missingChecks.join(", ")}
`);}else s.push(`
\u2705 All components have proper gate checks!
`);return s.join(`
`)}function L(e){let s=[],t=0;for(;t<e.length;){let n=e[t];if(/\s/.test(n)){t++;continue}if(n==='"'||n==="'"){let o=n,r="";for(t++;t<e.length&&e[t]!==o;)e[t]==="\\"&&t+1<e.length&&t++,r+=e[t],t++;t++,s.push({type:"STRING",value:r});continue}if(/\d/.test(n)){let o="";for(;t<e.length&&/[\d.]/.test(e[t]);)o+=e[t],t++;s.push({type:"NUMBER",value:o});continue}if(/[a-zA-Z_]/.test(n)){let o="";for(;t<e.length&&/[a-zA-Z0-9_]/.test(e[t]);)o+=e[t],t++;o==="true"||o==="false"?s.push({type:"BOOLEAN",value:o}):o==="null"||o==="undefined"?s.push({type:"NULL",value:o}):["and","or","not","includes","in"].includes(o)?s.push({type:"OPERATOR",value:o}):s.push({type:"IDENTIFIER",value:o});continue}if(e.slice(t,t+3)==="==="||e.slice(t,t+3)==="!=="){s.push({type:"OPERATOR",value:e.slice(t,t+3)}),t+=3;continue}if(e.slice(t,t+2)==="=="||e.slice(t,t+2)==="!="||e.slice(t,t+2)==="<="||e.slice(t,t+2)===">="||e.slice(t,t+2)==="&&"||e.slice(t,t+2)==="||"){s.push({type:"OPERATOR",value:e.slice(t,t+2)}),t+=2;continue}if("<>=!".includes(n)){s.push({type:"OPERATOR",value:n}),t++;continue}if(n==="("){s.push({type:"LPAREN",value:n}),t++;continue}if(n===")"){s.push({type:"RPAREN",value:n}),t++;continue}if(n==="."){s.push({type:"DOT",value:n}),t++;continue}if(n===","){s.push({type:"COMMA",value:n}),t++;continue}t++;}return s.push({type:"EOF",value:""}),s}var M=class{tokens;pos;context;constructor(e,s){this.tokens=e,this.pos=0,this.context=s;}current(){return this.tokens[this.pos]||{type:"EOF",value:""}}advance(){let e=this.current();return this.pos++,e}evaluate(){return this.parseOr()}parseOr(){let e=this.parseAnd();for(;this.current().value==="||"||this.current().value==="or";){this.advance();let s=this.parseAnd();e=!!e||!!s;}return e}parseAnd(){let e=this.parseNot();for(;this.current().value==="&&"||this.current().value==="and";){this.advance();let s=this.parseNot();e=!!e&&!!s;}return e}parseNot(){return this.current().value==="!"||this.current().value==="not"?(this.advance(),!this.parseNot()):this.parseComparison()}parseComparison(){let e=this.parsePrimary(),s=this.current();if(s.type==="OPERATOR")switch(s.value){case "==":case "===":return this.advance(),e===this.parsePrimary();case "!=":case "!==":return this.advance(),e!==this.parsePrimary();case "<":return this.advance(),e<this.parsePrimary();case ">":return this.advance(),e>this.parsePrimary();case "<=":return this.advance(),e<=this.parsePrimary();case ">=":return this.advance(),e>=this.parsePrimary();case "includes":this.advance();let t=this.parsePrimary();return Array.isArray(e)?e.includes(t):typeof e=="string"?e.includes(String(t)):false;case "in":this.advance();let n=this.parsePrimary();return Array.isArray(n)?n.includes(e):false}return e}parsePrimary(){let e=this.current();if(e.type==="LPAREN"){this.advance();let s=this.parseOr();return this.current().type==="RPAREN"&&this.advance(),s}return e.type==="STRING"?(this.advance(),e.value):e.type==="NUMBER"?(this.advance(),parseFloat(e.value)):e.type==="BOOLEAN"?(this.advance(),e.value==="true"):e.type==="NULL"?(this.advance(),null):e.type==="IDENTIFIER"?this.parseIdentifier():null}parseIdentifier(){let e=this.context;for(;this.current().type==="IDENTIFIER"||this.current().type==="DOT";){if(this.current().type==="DOT"){this.advance();continue}let s=this.advance().value;if(e!==null&&typeof e=="object"&&!Array.isArray(e)?e=e[s]:e=void 0,this.current().type==="LPAREN"){this.advance();let t=[];for(;this.current().type!=="RPAREN"&&this.current().type!=="EOF";)t.push(this.parseOr()),this.current().type==="COMMA"&&this.advance();return this.current().type==="RPAREN"&&this.advance(),this.callMethod(s,e,t)}if(this.current().type!=="DOT")break}return e}callMethod(e,s,t){switch(e){case "includes":return Array.isArray(s)?s.includes(t[0]):typeof s=="string"?s.includes(String(t[0])):false;case "startsWith":return typeof s=="string"?s.startsWith(String(t[0])):false;case "endsWith":return typeof s=="string"?s.endsWith(String(t[0])):false;case "length":return Array.isArray(s)||typeof s=="string"?s.length:0;default:return null}}};function S(e,s){try{let t=L(e);return {passed:!!new M(t,s).evaluate()}}catch(t){return {passed:false,error:t.message}}}var B=class{config;prizeHandlers=new Map;firedPrizes=[];ws=null;options;entityIdResolver;constructor(e,s={}){this.config=e,this.options=s,this.entityIdResolver=s.entityIdResolver||this.defaultEntityIdResolver,s.devMode&&this.connectWatcher();}defaultEntityIdResolver(e){return e.id||e._id||e.userId||e.entityId||"anonymous"}connectWatcher(){let e=this.options.watcherUrl||`ws://localhost:${this.config.settings.dev.watcherPort}`;try{typeof WebSocket<"u"&&(this.ws=new WebSocket(e),this.ws.onopen=()=>{console.log("[Gate SDK] Connected to watcher");},this.ws.onerror=()=>{console.warn("[Gate SDK] Failed to connect to watcher");},this.ws.onclose=()=>{setTimeout(()=>this.connectWatcher(),5e3);});}catch{console.warn("[Gate SDK] WebSocket not available for watcher connection");}}sendWatcherEvent(e){this.ws&&this.ws.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify(e));}onPrize(e,s){return this.prizeHandlers.has(e)||this.prizeHandlers.set(e,[]),this.prizeHandlers.get(e).push(s),()=>{let t=this.prizeHandlers.get(e);if(t){let n=t.indexOf(s);n>=0&&t.splice(n,1);}}}async check(e,s){let t=this.config.gates.find(a=>a.id===e);if(!t)throw new Error(`Gate not found: ${e}`);let n=this.entityIdResolver(s),o=Date.now();this.sendWatcherEvent({type:"gate:check",timestamp:o,entityId:n,data:{gate:t,entitySnapshot:s}});let r=[],i=true;for(let a of t.locks){let f=[],l;if(a.mode==="any"){l=false;for(let d of a.keys){let{passed:v,error:C}=S(d.expression,s);f.push({key:d,passed:v,error:C}),v&&(l=true);}}else {l=true;for(let d of a.keys){let{passed:v,error:C}=S(d.expression,s);f.push({key:d,passed:v,error:C}),v||(l=false);}}r.push({lock:a,passed:l,keyResults:f}),l||(i=false);}let c=[];if(i)for(let a of t.prizes){if(a.oneTime&&this.firedPrizes.some(d=>d.entityId===n&&d.prizeId===a.id))continue;c.push(a),a.oneTime&&this.firedPrizes.push({entityId:n,prizeId:a.id,timestamp:o});let f=this.prizeHandlers.get(a.id)||[];for(let l of f)try{await l(s,{gate:t,prize:a,timestamp:o});}catch(d){console.error(`[Gate SDK] Prize handler error for ${a.id}:`,d);}this.sendWatcherEvent({type:"prize:fire",timestamp:Date.now(),entityId:n,data:{prizeId:a.id,metadata:a.metadata}});}let u={gate:t,passed:i,lockResults:r,triggeredPrizes:c,timestamp:o,entitySnapshot:s};return this.sendWatcherEvent({type:i?"gate:pass":"gate:fail",timestamp:Date.now(),entityId:n,data:u}),u}getGate(e){return this.config.gates.find(s=>s.id===e)}getGates(){return this.config.gates}getFlows(){return this.config.flows}resetPrizes(e){e?this.firedPrizes=this.firedPrizes.filter(s=>s.entityId!==e):this.firedPrizes=[];}disconnect(){this.ws&&(this.ws.close(),this.ws=null);}};async function F(e,s={}){let t=await a(e),n=s.devMode??process.env.NODE_ENV!=="production";return new B(t,{...s,devMode:n})}typeof process<"u"?process.env.NODE_ENV==="production":typeof import.meta<"u"&&import.meta.env?.PROD;typeof process<"u"?process.env.PORTAL_VALIDATION==="true":typeof import.meta<"u"&&import.meta.env?.VITE_ENABLE_PORTAL_VALIDATION==="true";typeof process<"u"?process.env.PORTAL_TEST_MODE==="true":typeof import.meta<"u"&&import.meta.env?.VITE_TEST_MODE==="true";function $(e){let s=/\b([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)+)/g,t=new Set,n;for(;(n=s.exec(e))!==null;)t.add(n[1]);return [...t]}function b(e){let s=e.split("."),t={},n=t;for(let o=0;o<s.length;o++){let r=s[o];if(o===s.length-1)n[r]="test-value";else {let i={};n[r]=i,n=i;}}return t}function E(e,s){let t={...e};for(let[n,o]of Object.entries(s))o&&typeof o=="object"&&!Array.isArray(o)&&t[n]&&typeof t[n]=="object"&&!Array.isArray(t[n])?t[n]=E(t[n],o):t[n]=o;return t}function W(e){let s=[];if(!e.locks||e.locks.length===0)return s.push({name:`${e.id}: no locks (should pass)`,entity:{user:{id:"test-user"}},expected:true}),s;let t={};for(let n of e.locks)for(let o of n.keys){let r=$(o.expression);for(let i of r){let c=b(i);t=E(t,c);}}s.push({name:`${e.id}: entity satisfying all locks (should pass)`,entity:t,expected:true});for(let n of e.locks){let o=[];for(let r of n.keys)o.push(...$(r.expression));if(o.length>0){let r={};for(let i of e.locks)if(i.id!==n.id)for(let c of i.keys){let u=$(c.expression);for(let a of u){let f=b(a);Object.assign(r,E(r,f));}}s.push({name:`${e.id}: missing lock "${n.id}" properties (should fail)`,entity:e.locks.length===1?{}:r,expected:false});}}return s}async function le(e,s){let t=e?y.resolve(e):process.cwd(),n=y.join(t,"portal.yaml");if(h.existsSync(n)||(console.error(p.red(`\u274C portal.yaml not found at ${n}`)),console.error(p.gray("   Run `paradigm init` or create portal.yaml manually")),process.exit(1)),s.generate){console.log(p.blue(`
\u{1F527} Generating test files...
`));try{let o=await T(n,{outputDir:s.output||"tests/gates",framework:s.framework||"jest",includeFlows:!0});console.log(p.green(`\u2705 Generated ${o.length} test files:`));for(let r of o)console.log(p.gray(`   ${y.relative(t,r)}`));console.log("");}catch(o){console.error(p.red(`\u274C Error generating tests: ${o.message}`)),process.exit(1);}return}if(s.component){console.log(p.blue(`
\u{1F50D} Scanning components for gate checks...
`));try{let o=await x({rootDir:t,gateConfigPath:n}),r=P(o);console.log(r),o.filter(c=>c.missingChecks.length>0).length>0&&process.exit(1);}catch(o){console.error(p.red(`\u274C Error scanning components: ${o.message}`)),process.exit(1);}return}if(s.gate){console.log(p.blue(`
\u{1F9EA} Testing gate: ${s.gate}
`));try{let o=await a(n),r=await F(n);G(r);let i=o.gates.find(a=>a.id===s.gate);i||(console.error(p.red(`\u274C Gate "${s.gate}" not found`)),process.exit(1));let c=[{name:"Empty entity (should fail)",entity:{},expected:!1},...W(i)],u=await O(s.gate,c,r);if(u.passed)console.log(p.green(`\u2705 All tests passed
`));else {console.log(p.red(`\u274C Some tests failed
`));for(let a of u.errors)console.log(p.red(`   ${a}`));console.log(""),process.exit(1);}}catch(o){console.error(p.red(`\u274C Error testing gate: ${o.message}`)),process.exit(1);}return}console.log(p.blue(`
\u{1F9EA} Portal Testing
`)),console.log("Usage:"),console.log("  paradigm portal test --generate             Generate test files"),console.log("  paradigm portal test --portal ^auth-required  Test specific portal"),console.log("  paradigm portal test --component             Validate component access"),console.log("");}export{le as gateTestCommand};