"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mobileFindDescriptorSchema = exports.webViewFindElementDescriptorSchema = exports.mobileFindCustomDescriptorSchema = exports.mobileFindElementDescriptorSchema = exports.findDescriptorSchema = exports.findTabDescriptorSchema = exports.findEmailDescriptorSchema = exports.findCookieDescriptorSchema = exports.findCustomDescriptorSchema = exports.findElementDescriptorSchema = exports.browserFindDescriptorSchema = exports.browserFindTargetSchema = exports.cookieSelectorSchema = exports.mobileFindSpecificationSchema = exports.mobileElementSelectorSchema = exports.normalizedFindDescriptorSchema = exports.mobileFindOptionsSchema = exports.findOptionsSchema = exports.customCssSelectorSchema = exports.customXpathSelectorSchema = exports.simpleElementSelectorSchema = exports.primaryFindMethodEnum = exports.propertyComparatorEnum = exports.elementExpectationEnum = exports.confidenceLevelEnum = exports.customFindTypeEnum = exports.findTypeEnum = void 0;
const zod_1 = require("zod");
exports.findTypeEnum = zod_1.z.enum([
    'find_all',
    'find_any',
    'find_cookie',
    'find_email',
    'find_first',
    'find_last',
    'find_one',
    'find_tab',
]);
exports.customFindTypeEnum = zod_1.z.enum([
    'find_all',
    'find_any',
    'find_first',
    'find_last',
]);
exports.confidenceLevelEnum = zod_1.z.enum(['low', 'medium', 'high', 'unknown']);
exports.elementExpectationEnum = zod_1.z.enum(['missing', 'present']);
exports.propertyComparatorEnum = zod_1.z.enum(['equals', 'contains']);
exports.primaryFindMethodEnum = zod_1.z
    .enum(['1', '2', '3'])
    .describe('Primary element finding strategy: 1 = native attributes, 2 = element description (AI), 3 = XPath only');
const selectorElementAttributeSchema = zod_1.z
    .object({
    name: zod_1.z.string().optional(),
    id: zod_1.z.string().optional(),
    value: zod_1.z.string().optional(),
    is_truncated: zod_1.z.boolean().optional(),
})
    .passthrough();
const NEW_SHAPE_KEYS = new Set([
    'uuid',
    'xpath',
    'locator',
    'description',
    'find_prompt',
]);
exports.simpleElementSelectorSchema = zod_1.z
    .object({
    uuid: zod_1.z
        .string()
        .describe('Stable identifier for this descriptor. Used by the runtime to key captured fingerprints into the selector store. Generate one new uuid per logical element and reuse it across re-authors of the same target — re-authoring with a new uuid loses accumulated heal data.'),
    xpath: zod_1.z
        .string()
        .describe('LEGACY: structural XPath captured by the trainer. New authoring should not populate this field — use `locator` instead (with the xpath wrapped as a Playwright locator value, e.g. "xpath=//button" or a leading "//" for auto-detection). Kept here for backwards compatibility with trainer-recorded descriptors.')
        .optional(),
    alt: zod_1.z.string().optional(),
    aria_controls: zod_1.z.string().optional(),
    aria_label: zod_1.z.string().optional(),
    aria_labelledby: zod_1.z.string().optional(),
    aria_owns: zod_1.z.string().optional(),
    autocomplete: zod_1.z.string().optional(),
    bounding_height: zod_1.z.string().optional(),
    bounding_width: zod_1.z.string().optional(),
    bounding_x: zod_1.z.string().optional(),
    bounding_y: zod_1.z.string().optional(),
    class_name: zod_1.z.string().optional(),
    clickable: zod_1.z.string().optional(),
    css_query: zod_1.z.string().optional(),
    data_autobot_element_id: zod_1.z.string().optional(),
    automationid: zod_1.z.string().optional(),
    objectid: zod_1.z.string().optional(),
    icon_id: zod_1.z.string().optional(),
    data_automation_id: zod_1.z.string().optional(),
    data_id: zod_1.z.string().optional(),
    data_name: zod_1.z.string().optional(),
    data_prop: zod_1.z.string().optional(),
    data_target: zod_1.z.string().optional(),
    data_test_id: zod_1.z.string().optional(),
    data_testid: zod_1.z.string().optional(),
    data_tracking: zod_1.z.string().optional(),
    data_value: zod_1.z.string().optional(),
    find_prompt: zod_1.z
        .string()
        .describe('LEGACY alias for `description`. New authoring should use `description` instead. Reads from this field still flow into the description-driven (visual LLM) resolver as a fallback when `description` is absent.')
        .optional(),
    findable_ancestor_uuid: zod_1.z.string().optional(),
    for_attr: zod_1.z.string().optional(),
    form: zod_1.z.string().optional(),
    height: zod_1.z.string().optional(),
    href: zod_1.z.string().optional(),
    id: zod_1.z.string().optional(),
    index: zod_1.z.string().optional(),
    inputElementType: zod_1.z.string().optional(),
    item: zod_1.z.string().optional(),
    label_attr: zod_1.z.string().optional(),
    label: zod_1.z.string().optional(),
    maxlength: zod_1.z.string().optional(),
    name: zod_1.z.string().optional(),
    ng_class: zod_1.z.string().optional(),
    ng_model: zod_1.z.string().optional(),
    ng_show: zod_1.z.string().optional(),
    other_attributes: zod_1.z
        .union([zod_1.z.array(selectorElementAttributeSchema), zod_1.z.string()])
        .optional(),
    placeholder: zod_1.z.string().optional(),
    relative_xpath: zod_1.z.string().optional(),
    repeat_xpaths: zod_1.z.array(zod_1.z.string()).optional(),
    role: zod_1.z.string().optional(),
    selector_type: zod_1.z.enum(['element', 'element_group']).optional(),
    src: zod_1.z.string().optional(),
    style: zod_1.z.string().optional(),
    tabindex: zod_1.z.string().optional(),
    tag_name: zod_1.z.string().optional(),
    target: zod_1.z.string().optional(),
    test_id: zod_1.z.string().optional(),
    text: zod_1.z.string().optional(),
    slot_text: zod_1.z.string().optional(),
    title_attr: zod_1.z.string().optional(),
    title: zod_1.z.string().optional(),
    url: zod_1.z.string().optional(),
    value: zod_1.z.string().optional(),
    visible: zod_1.z.string().optional(),
    width: zod_1.z.string().optional(),
    namespace_uri: zod_1.z.string().optional(),
    window_width: zod_1.z.string().optional(),
    window_height: zod_1.z.string().optional(),
    locator: zod_1.z
        .string()
        .describe('A Playwright locator string identifying the target element. Pick the most stable identifier available — data-test-id > role= > id > unique CSS class > generic XPath. Must resolve to exactly one element; express any needed narrowing inside the locator string using ">>", ":has-text(...)", "nth=N", etc. On resolution failure or low-confidence rejection the runtime falls through to description-driven visual find. See the JSDoc on simpleElementSelectorSchema for the full Playwright grammar.')
        .optional(),
    description: zod_1.z
        .string()
        .describe('Natural-language statement of what the element is and its function. Drives the visual-LLM fallback when the locator fails. Describe what the element is and does, not how it looks. Good: "primary submit button on the checkout form". Bad: "the blue button above the cart summary".')
        .optional(),
})
    .passthrough()
    .superRefine((data, ctx) => {
    const hasXpath = typeof data.xpath === 'string' && data.xpath.length > 0;
    const hasLocator = typeof data.locator === 'string' && data.locator.length > 0;
    const hasDescription = typeof data.description === 'string' && data.description.length > 0;
    const hasFindPrompt = typeof data.find_prompt === 'string' && data.find_prompt.length > 0;
    if (!hasXpath && !hasLocator && !hasDescription && !hasFindPrompt) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: 'SimpleElementSelector requires at least one of `xpath`, `locator`, or `description`. `locator` is a Playwright locator string; `description` is the canonical intent statement and routes to the description-driven (visual) resolver. Always provide `description` when you can — `locator` is the optional fast path.',
            path: ['xpath'],
        });
    }
    const trainerShapeKeys = Object.keys(data).filter((k) => !NEW_SHAPE_KEYS.has(k));
    if (trainerShapeKeys.length > 0 && !hasXpath) {
        ctx.addIssue({
            code: zod_1.z.ZodIssueCode.custom,
            message: `SimpleElementSelector with trainer-shape attribute fields (${trainerShapeKeys
                .slice(0, 5)
                .map((k) => '`' + k + '`')
                .join(', ')}${trainerShapeKeys.length > 5 ? ', ...' : ''}) requires \`xpath\` as the structural anchor for the legacy attribute-scoring resolver. Either add \`xpath\`, or remove the attribute fields and author a pure new-shape descriptor with only \`uuid\`, \`locator\`, \`description\` (and optionally \`find_prompt\`).`,
            path: ['xpath'],
        });
    }
});
exports.customXpathSelectorSchema = zod_1.z
    .object({
    xpath: zod_1.z.string(),
    uuid: zod_1.z.string().optional(),
})
    .passthrough();
exports.customCssSelectorSchema = zod_1.z
    .object({
    css_query: zod_1.z.string(),
    uuid: zod_1.z.string().optional(),
})
    .passthrough();
const autoHealOptionsSchema = zod_1.z
    .object({
    isAutoHealAuthorized: zod_1.z.boolean(),
    useLegacyAutoheal: zod_1.z
        .boolean()
        .describe('For descriptors with a new-shape `locator` field, controls whether ' +
        'failure of the locator + description-driven visual chain falls ' +
        'through to the legacy attribute-scoring + ' +
        'AdvancedAutoHealFindStrategy pipeline. Default true preserves the ' +
        'legacy heal safety net. Set false to use only the locator + ' +
        'description chain; intended for authors and migrations after the ' +
        'confidence-driven selector learning loop is in place. Ignored for ' +
        'pure legacy descriptors (those without a `locator` field).')
        .optional(),
})
    .passthrough();
const waitUntilPropertiesSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.array(zod_1.z.string()));
const waitUntilSchema = zod_1.z
    .object({
    timeoutSeconds: zod_1.z.number(),
    properties: waitUntilPropertiesSchema.optional(),
})
    .passthrough();
const findHintsSchema = zod_1.z
    .object({
    elementExpectation: exports.elementExpectationEnum.optional(),
    isElementPresenceEvaluation: zod_1.z.boolean().optional(),
    isFindForAssertion: zod_1.z.boolean().optional(),
    selectorSubstitutions: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
})
    .passthrough();
const findTrainingHintsSchema = zod_1.z
    .object({
    confidenceLevel: exports.confidenceLevelEnum.optional(),
    shadowParentsFindingConfidence: exports.confidenceLevelEnum.optional(),
    repeatedElementDetected: zod_1.z.array(zod_1.z.enum(['target', 'ancestor'])).optional(),
    selectorEvalMillis: zod_1.z.number().optional(),
})
    .passthrough();
exports.findOptionsSchema = zod_1.z
    .object({
    autoHealOptions: autoHealOptionsSchema.optional(),
    hints: findHintsSchema.optional(),
    primaryFindMethod: exports.primaryFindMethodEnum.optional(),
    trainingHints: findTrainingHintsSchema.optional(),
    waitUntil: waitUntilSchema.optional(),
})
    .passthrough();
exports.mobileFindOptionsSchema = exports.findOptionsSchema.extend({
    onlyFindByXPath: zod_1.z.boolean().optional(),
});
const findOrdinalPreferenceSchema = zod_1.z.object({
    position: zod_1.z.number(),
    ascending: zod_1.z.boolean(),
});
const findPropertyPreferenceSchema = zod_1.z.object({
    comparator: exports.propertyComparatorEnum.optional(),
    intended: zod_1.z.boolean(),
    value: zod_1.z.string().optional(),
});
const selectorConfigurationSchema = zod_1.z
    .object({
    ordinalPreference: findOrdinalPreferenceSchema.optional(),
    propertyPreferences: zod_1.z
        .record(zod_1.z.string(), findPropertyPreferenceSchema)
        .optional(),
})
    .passthrough();
const baseSelectorHolderSchema = zod_1.z
    .object({
    overrides: zod_1.z.array(zod_1.z.unknown()).optional(),
    findModel: zod_1.z.unknown().optional(),
    evaluation: zod_1.z.unknown().optional(),
    selectorVariantId: zod_1.z.string().optional(),
})
    .passthrough();
exports.normalizedFindDescriptorSchema = zod_1.z.lazy(() => baseSelectorHolderSchema.extend({
    selector: exports.simpleElementSelectorSchema,
    originalSelector: exports.simpleElementSelectorSchema.optional(),
    auxiliaryDescriptors: zod_1.z.array(exports.normalizedFindDescriptorSchema).optional(),
    configuration: selectorConfigurationSchema.optional(),
    findOptions: exports.findOptionsSchema.optional(),
    findSummaries: zod_1.z.array(zod_1.z.unknown()).optional(),
    type: exports.findTypeEnum.optional(),
    shadowParents: zod_1.z.array(exports.simpleElementSelectorSchema).optional(),
}));
const commonMobileElementSelectorSchema = zod_1.z
    .object({
    enabled: zod_1.z.boolean().optional(),
    find_prompt: zod_1.z.string().optional(),
    index: zod_1.z.number().optional(),
    rect: zod_1.z
        .object({
        x: zod_1.z.number(),
        y: zod_1.z.number(),
        width: zod_1.z.number(),
        height: zod_1.z.number(),
    })
        .optional(),
    screenSize: zod_1.z
        .object({
        height: zod_1.z.number(),
        width: zod_1.z.number(),
    })
        .optional(),
    selected: zod_1.z.boolean().optional(),
    xpath: zod_1.z.string().optional(),
    alternateXPaths: zod_1.z.array(zod_1.z.string()).optional(),
    uuid: zod_1.z.string().optional(),
})
    .passthrough();
const iOSElementSelectorSchema = commonMobileElementSelectorSchema.extend({
    label: zod_1.z.string().optional(),
    name: zod_1.z.string().optional(),
    type: zod_1.z.string().optional(),
    value: zod_1.z.string().optional(),
    visible: zod_1.z.boolean().optional(),
});
const androidElementSelectorSchema = commonMobileElementSelectorSchema.extend({
    bounds: zod_1.z.string().optional(),
    checkable: zod_1.z.boolean().optional(),
    checked: zod_1.z.boolean().optional(),
    class: zod_1.z.string().optional(),
    clickable: zod_1.z.boolean().optional(),
    contentDesc: zod_1.z.string().optional(),
    displayed: zod_1.z.boolean().optional(),
    focusable: zod_1.z.boolean().optional(),
    focused: zod_1.z.boolean().optional(),
    hint: zod_1.z.string().optional(),
    longClickable: zod_1.z.boolean().optional(),
    package: zod_1.z.string().optional(),
    password: zod_1.z.boolean().optional(),
    resourceId: zod_1.z.string().optional(),
    scrollable: zod_1.z.boolean().optional(),
    text: zod_1.z.string().optional(),
});
exports.mobileElementSelectorSchema = zod_1.z
    .object({
    uuid: zod_1.z.string(),
    iOS: iOSElementSelectorSchema.optional(),
    android: androidElementSelectorSchema.optional(),
})
    .passthrough();
exports.mobileFindSpecificationSchema = zod_1.z.lazy(() => baseSelectorHolderSchema.extend({
    selector: exports.mobileElementSelectorSchema,
    originalSelector: exports.mobileElementSelectorSchema.optional(),
    auxiliaryDescriptors: zod_1.z.array(exports.mobileFindSpecificationSchema).optional(),
    configuration: selectorConfigurationSchema.optional(),
    findOptions: exports.mobileFindOptionsSchema.optional(),
    findSummaries: zod_1.z.array(zod_1.z.unknown()).optional(),
    type: exports.findTypeEnum.optional(),
    shadowParents: zod_1.z.array(exports.mobileElementSelectorSchema).optional(),
}));
exports.cookieSelectorSchema = zod_1.z
    .object({
    name: zod_1.z.string(),
    url: zod_1.z.string().optional(),
    same_site: zod_1.z.enum(['Strict', 'Lax', 'None']).optional(),
    domain: zod_1.z.string().optional(),
    expiry: zod_1.z.number().optional(),
    http_only: zod_1.z.boolean().optional(),
    path: zod_1.z.string().optional(),
    secure: zod_1.z.boolean().optional(),
    value: zod_1.z.string().optional(),
})
    .passthrough();
exports.browserFindTargetSchema = zod_1.z.union([
    exports.normalizedFindDescriptorSchema,
    exports.simpleElementSelectorSchema,
    exports.customCssSelectorSchema,
    exports.customXpathSelectorSchema,
]);
exports.browserFindDescriptorSchema = zod_1.z
    .object({
    findType: exports.findTypeEnum,
    findTarget: exports.browserFindTargetSchema,
    findOptions: exports.findOptionsSchema.optional(),
})
    .passthrough();
exports.findElementDescriptorSchema = exports.browserFindDescriptorSchema;
exports.findCustomDescriptorSchema = exports.browserFindDescriptorSchema;
exports.findCookieDescriptorSchema = zod_1.z
    .object({
    findType: zod_1.z.literal('find_cookie'),
    findTarget: exports.cookieSelectorSchema,
})
    .passthrough();
exports.findEmailDescriptorSchema = zod_1.z
    .object({
    findType: zod_1.z.literal('find_email'),
    findTarget: zod_1.z.unknown(),
})
    .passthrough();
exports.findTabDescriptorSchema = zod_1.z
    .object({
    findType: zod_1.z.literal('find_tab'),
    findTarget: zod_1.z.unknown(),
})
    .passthrough();
exports.findDescriptorSchema = zod_1.z.union([
    exports.findCookieDescriptorSchema,
    exports.findEmailDescriptorSchema,
    exports.findTabDescriptorSchema,
    exports.browserFindDescriptorSchema,
]);
exports.mobileFindElementDescriptorSchema = zod_1.z
    .object({
    findType: zod_1.z.literal('find_one'),
    findTarget: exports.mobileFindSpecificationSchema,
    findOptions: exports.mobileFindOptionsSchema.optional(),
})
    .passthrough();
exports.mobileFindCustomDescriptorSchema = zod_1.z
    .object({
    findType: exports.customFindTypeEnum,
    findTarget: exports.customXpathSelectorSchema,
    foundElementSelectors: zod_1.z
        .union([
        exports.mobileElementSelectorSchema,
        zod_1.z.tuple([exports.mobileElementSelectorSchema, exports.mobileElementSelectorSchema]),
    ])
        .optional(),
    primarySelectors: exports.customXpathSelectorSchema.optional(),
    findOptions: exports.findOptionsSchema.optional(),
})
    .passthrough();
exports.webViewFindElementDescriptorSchema = exports.mobileFindElementDescriptorSchema.extend({
    webView: zod_1.z.object({
        descriptor: zod_1.z.union([
            exports.findCustomDescriptorSchema,
            exports.findElementDescriptorSchema,
            exports.findCookieDescriptorSchema,
        ]),
        title: zod_1.z.string(),
        url: zod_1.z.string(),
    }),
});
exports.mobileFindDescriptorSchema = zod_1.z.union([
    exports.webViewFindElementDescriptorSchema,
    exports.mobileFindElementDescriptorSchema,
    exports.mobileFindCustomDescriptorSchema,
]);
