import { RegistryType, } from './IRegistry.js';
export class HttpError extends Error {
    status;
    body;
    constructor(message, status, body = null) {
        super(message);
        this.name = 'HttpError';
        this.status = status;
        this.body = body;
    }
}
export class HttpClientRegistry {
    baseUrl;
    type = RegistryType.Http;
    uri;
    unimplementedMethods = new Set([
        'getUri',
        'getChainLogoUri',
        'addChain',
        'removeChain',
        'addWarpRoute',
        'getWarpDeployConfig',
        'getWarpDeployConfigs',
        'addWarpRouteConfig',
        'merge',
    ]);
    constructor(baseUrl = 'http://localhost:3001') {
        this.baseUrl = baseUrl;
        this.uri = baseUrl;
    }
    getMetadata() {
        return this.fetchJson('/metadata');
    }
    getAddresses() {
        return this.fetchJson('/addresses');
    }
    getUri(_itemPath) {
        throw new Error('Method not implemented.');
    }
    listRegistryContent() {
        return this.fetchJson('/list-registry-content');
    }
    getChains() {
        return this.fetchJson('/chains');
    }
    async getChainMetadata(chainName) {
        try {
            return await this.fetchJson(`/chain/${chainName}/metadata`);
        }
        catch (e) {
            if (e instanceof HttpError && e.status === 404) {
                return null;
            }
            throw e;
        }
    }
    async getChainAddresses(chainName) {
        try {
            return await this.fetchJson(`/chain/${chainName}/addresses`);
        }
        catch (e) {
            if (e instanceof HttpError && e.status === 404) {
                return null;
            }
            throw e;
        }
    }
    async updateChain(update) {
        await this.fetchJson(`/chain/${update.chainName}`, {
            method: 'POST',
            body: JSON.stringify({
                metadata: update.metadata,
                addresses: update.addresses,
            }),
            headers: {
                'Content-Type': 'application/json',
            },
        });
    }
    getChainLogoUri(_chainName) {
        throw new Error('Method not implemented.');
    }
    addChain(_chain) {
        throw new Error('Method not implemented.');
    }
    removeChain(_chain) {
        throw new Error('Method not implemented.');
    }
    getWarpRoute(routeId) {
        return this.fetchJson(`/warp-route/core/${routeId}`);
    }
    getWarpRoutes(filter) {
        const queryParams = new URLSearchParams();
        if (filter?.symbol) {
            queryParams.set('symbol', filter.symbol);
        }
        if (filter?.label) {
            queryParams.set('label', filter.label);
        }
        return this.fetchJson(`/warp-route/core?${queryParams.toString()}`);
    }
    addWarpRoute(_config) {
        throw new Error('Method not implemented.');
    }
    getWarpDeployConfig(routeId) {
        return this.fetchJson(`/warp-route/deploy/${routeId}`);
    }
    getWarpDeployConfigs() {
        throw new Error('Method not implemented.');
    }
    addWarpRouteConfig(_config, _options) {
        throw new Error('Method not implemented.');
    }
    merge(_otherRegistry) {
        throw new Error('Method not implemented.');
    }
    async fetchJson(endpoint, options = {}) {
        const requestOptions = { ...options };
        // Only add JSON content-type header if there's a body
        if (options.body) {
            requestOptions.headers = {
                'Content-Type': 'application/json',
                ...options.headers,
            };
        }
        const response = await fetch(`${this.baseUrl}${endpoint}`, requestOptions);
        // Handle successful requests that have no content to parse.
        if (response.status === 204) {
            return null;
        }
        if (!response.ok) {
            let errorBody = null;
            let errorMessage = `HTTP Error: ${response.status} ${response.statusText}`;
            try {
                errorBody = await response.json();
                // Use the server's detailed error message if available
                if (errorBody?.message) {
                    errorMessage = errorBody.message;
                }
            }
            catch (e) {
                // Ignore if error body isn't valid JSON, use statusText instead.
            }
            // Throw the structured error
            throw new HttpError(errorMessage, response.status, errorBody);
        }
        return response.json();
    }
}
