import { parseStructuredParams } from "../common.mjs";
import { BasePlaygroundAdapter } from "./base.mjs";
function _define_property(obj, key, value) {
    if (key in obj) Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
    });
    else obj[key] = value;
    return obj;
}
class RemoteExecutionAdapter extends BasePlaygroundAdapter {
    onDumpUpdate(callback) {
        this.dumpUpdateCallback = void 0;
        this.dumpUpdateCallback = callback;
    }
    get id() {
        return this._id;
    }
    validateParams(value, action) {
        if (!action?.paramSchema) return {
            valid: true
        };
        const needsStructuredParams = this.actionNeedsStructuredParams(action);
        if (!needsStructuredParams) return {
            valid: true
        };
        if (!value.params) return {
            valid: false,
            errorMessage: 'Parameters are required'
        };
        if (action.paramSchema && 'object' == typeof action.paramSchema) {
            const schema = action.paramSchema;
            if (schema.shape || 'ZodObject' === schema.type) {
                const shape = schema.shape || {};
                const missingFields = Object.keys(shape).filter((key)=>{
                    const fieldDef = shape[key];
                    const isOptional = fieldDef?.isOptional || fieldDef?._def?.innerType || fieldDef?._def?.typeName === 'ZodOptional';
                    return !isOptional && (void 0 === value.params[key] || '' === value.params[key]);
                });
                if (missingFields.length > 0) return {
                    valid: false,
                    errorMessage: `Missing required parameters: ${missingFields.join(', ')}`
                };
            }
        }
        return {
            valid: true
        };
    }
    async parseStructuredParams(action, params, options) {
        return await parseStructuredParams(action, params, options);
    }
    formatErrorMessage(error) {
        const message = error?.message || '';
        const androidErrors = [
            {
                keyword: 'adb',
                message: 'ADB connection error. Please ensure device is connected and USB debugging is enabled.'
            },
            {
                keyword: 'UIAutomator',
                message: 'UIAutomator error. Please ensure the UIAutomator server is running on the device.'
            }
        ];
        const androidError = androidErrors.find(({ keyword })=>message.includes(keyword));
        if (androidError) return androidError.message;
        return this.formatBasicErrorMessage(error);
    }
    async executeAction(actionType, value, options) {
        if (this.serverUrl && 'undefined' != typeof window) return this.executeViaServer(actionType, value, options);
        throw new Error('Remote execution adapter requires server URL for execution');
    }
    async executeViaServer(actionType, value, options) {
        const payload = {
            type: actionType,
            prompt: value.prompt,
            ...this.buildOptionalPayloadParams(options, value)
        };
        if (options.context) payload.context = options.context;
        if (options.requestId && this.dumpUpdateCallback) this.startProgressPolling(options.requestId);
        try {
            const response = await fetch(`${this.serverUrl}/execute`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload)
            });
            if (!response.ok) {
                const errorText = await response.text().catch(()=>'Unknown error');
                throw new Error(`Server request failed (${response.status}): ${errorText}`);
            }
            const result = await response.json();
            return result;
        } catch (error) {
            console.error('Execute via server failed:', error);
            throw error;
        } finally{
            this.stopProgressPolling();
        }
    }
    buildOptionalPayloadParams(options, value) {
        const optionalParams = {};
        const optionalFields = [
            {
                key: 'requestId',
                value: options.requestId
            },
            {
                key: 'deepLocate',
                value: options.deepLocate
            },
            {
                key: 'deepThink',
                value: options.deepThink
            },
            {
                key: 'screenshotIncluded',
                value: options.screenshotIncluded
            },
            {
                key: 'domIncluded',
                value: options.domIncluded
            },
            {
                key: 'deviceOptions',
                value: options.deviceOptions
            },
            {
                key: 'params',
                value: value.params
            }
        ];
        optionalFields.forEach(({ key, value })=>{
            if (null != value && '' !== value) optionalParams[key] = value;
        });
        return optionalParams;
    }
    async getActionSpace(context) {
        if (this.serverUrl && 'undefined' != typeof window) try {
            const response = await fetch(`${this.serverUrl}/action-space`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    context
                })
            });
            if (!response.ok) throw new Error(`Failed to get action space: ${response.statusText}`);
            const result = await response.json();
            return Array.isArray(result) ? result : [];
        } catch (error) {
            console.error('Failed to get action space from server:', error);
        }
        if (context && 'object' == typeof context && 'actionSpace' in context) try {
            const actionSpaceMethod = context.actionSpace;
            const result = await actionSpaceMethod();
            return Array.isArray(result) ? result : [];
        } catch (error) {
            console.error('Failed to get action space from context:', error);
        }
        return [];
    }
    async checkStatus() {
        if (!this.serverUrl) return false;
        try {
            const res = await fetch(`${this.serverUrl}/status`);
            if (200 === res.status) {
                try {
                    const data = await res.json();
                    if (data.id && 'string' == typeof data.id) this._id = data.id;
                } catch (jsonError) {
                    console.debug('Failed to parse status response:', jsonError);
                }
                return true;
            }
            return false;
        } catch (error) {
            console.warn('Server status check failed:', error);
            return false;
        }
    }
    async overrideConfig(aiConfig) {
        if (!this.serverUrl) throw new Error('Server URL not configured');
        try {
            const response = await fetch(`${this.serverUrl}/config`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    aiConfig
                })
            });
            if (!response.ok) {
                const body = await response.json().catch(()=>null);
                const detail = body?.error || response.statusText;
                throw new Error(detail);
            }
        } catch (error) {
            console.error('Failed to override server config:', error);
            throw error;
        }
    }
    async runConnectivityTest() {
        if (!this.serverUrl) throw new Error('Server URL not configured');
        const response = await fetch(`${this.serverUrl}/connectivity-test`, {
            method: 'POST'
        });
        if (!response.ok) {
            const body = await response.json().catch(()=>null);
            const detail = body?.error || response.statusText;
            throw new Error(detail);
        }
        return response.json();
    }
    async getTaskProgress(requestId) {
        if (!this.serverUrl) return {};
        if (!requestId?.trim()) {
            console.warn('Invalid requestId provided for task progress');
            return {};
        }
        try {
            const response = await fetch(`${this.serverUrl}/task-progress/${encodeURIComponent(requestId)}`);
            if (!response.ok) {
                console.warn(`Task progress request failed: ${response.statusText}`);
                return {};
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to poll task progress:', error);
            return {};
        }
    }
    startProgressPolling(requestId) {
        this.stopProgressPolling();
        this.pollingIntervalId = setInterval(async ()=>{
            try {
                const progressData = await this.getTaskProgress(requestId);
                if (progressData.executionDump) {
                    if (this.dumpUpdateCallback) this.dumpUpdateCallback('', progressData.executionDump);
                }
            } catch (error) {
                console.error('Error polling task progress:', error);
            }
        }, 500);
    }
    stopProgressPolling() {
        if (this.pollingIntervalId) {
            clearInterval(this.pollingIntervalId);
            this.pollingIntervalId = void 0;
        }
    }
    async cancelTask(requestId) {
        if (!this.serverUrl) return {
            error: 'No server URL configured'
        };
        if (!requestId?.trim()) return {
            error: 'Invalid request ID'
        };
        try {
            const res = await fetch(`${this.serverUrl}/cancel/${encodeURIComponent(requestId)}`, {
                method: 'POST'
            });
            if (!res.ok) return {
                error: `Cancel request failed: ${res.statusText}`
            };
            const result = await res.json();
            return {
                success: true,
                ...result
            };
        } catch (error) {
            console.error('Failed to cancel task:', error);
            return {
                error: 'Failed to cancel task'
            };
        }
    }
    async getScreenshot() {
        if (!this.serverUrl) return null;
        try {
            const response = await fetch(`${this.serverUrl}/screenshot`);
            if (!response.ok) {
                if (409 !== response.status) console.warn(`Screenshot request failed: ${response.statusText}`);
                return null;
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to get screenshot:', error);
            return null;
        }
    }
    async interact(payload) {
        if (!this.serverUrl) return {
            ok: false,
            error: 'No server URL configured'
        };
        try {
            const response = await fetch(`${this.serverUrl}/interact`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload)
            });
            const data = await response.json().catch(()=>null);
            if (!response.ok) return {
                ok: false,
                error: data?.error || `Interact request failed (${response.status})`
            };
            return {
                ok: true
            };
        } catch (error) {
            return {
                ok: false,
                error: error instanceof Error ? error.message : 'Unknown error'
            };
        }
    }
    async getInterfaceInfo() {
        if (!this.serverUrl) return null;
        try {
            const response = await fetch(`${this.serverUrl}/interface-info`);
            if (!response.ok) {
                console.warn(`Interface info request failed: ${response.statusText}`);
                return null;
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to get interface info:', error);
            return null;
        }
    }
    async getRuntimeInfo() {
        if (!this.serverUrl) return null;
        try {
            const response = await fetch(`${this.serverUrl}/runtime-info`);
            if (!response.ok) {
                console.warn(`Runtime info request failed: ${response.statusText}`);
                return null;
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to get runtime info:', error);
            return null;
        }
    }
    async getSessionInfo() {
        if (!this.serverUrl) return null;
        try {
            const response = await fetch(`${this.serverUrl}/session`);
            if (!response.ok) {
                console.warn(`Session info request failed: ${response.statusText}`);
                return null;
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to get session info:', error);
            return null;
        }
    }
    async getSessionSetup(input) {
        if (!this.serverUrl) return null;
        try {
            const searchParams = new URLSearchParams();
            Object.entries(input || {}).forEach(([key, value])=>{
                if ('string' == typeof value || 'number' == typeof value || 'boolean' == typeof value) searchParams.set(key, String(value));
            });
            const suffix = searchParams.size > 0 ? `?${searchParams.toString()}` : '';
            const response = await fetch(`${this.serverUrl}/session/setup${suffix}`);
            if (!response.ok) {
                const body = await response.json().catch(()=>null);
                throw new Error(body?.error || response.statusText || 'Failed to load session setup');
            }
            return await response.json();
        } catch (error) {
            console.error('Failed to get session setup:', error);
            throw error;
        }
    }
    async listSessionTargets() {
        if (!this.serverUrl) return [];
        try {
            const response = await fetch(`${this.serverUrl}/session/targets`);
            if (!response.ok) {
                const body = await response.json().catch(()=>null);
                throw new Error(body?.error || response.statusText || 'Failed to load session targets');
            }
            const result = await response.json();
            return Array.isArray(result) ? result : [];
        } catch (error) {
            console.error('Failed to get session targets:', error);
            throw error;
        }
    }
    async createSession(input) {
        if (!this.serverUrl) throw new Error('Server URL not configured');
        const response = await fetch(`${this.serverUrl}/session`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(input || {})
        });
        if (!response.ok) {
            const body = await response.json().catch(()=>null);
            throw new Error(body?.error || response.statusText);
        }
        return await response.json();
    }
    async destroySession() {
        if (!this.serverUrl) throw new Error('Server URL not configured');
        const response = await fetch(`${this.serverUrl}/session`, {
            method: 'DELETE'
        });
        if (!response.ok) {
            const body = await response.json().catch(()=>null);
            throw new Error(body?.error || response.statusText);
        }
        return await response.json();
    }
    constructor(serverUrl){
        super(), _define_property(this, "serverUrl", void 0), _define_property(this, "_id", void 0), _define_property(this, "dumpUpdateCallback", void 0), _define_property(this, "pollingIntervalId", void 0);
        this.serverUrl = serverUrl;
    }
}
export { RemoteExecutionAdapter };

//# sourceMappingURL=remote-execution.mjs.map