import { throwIncompatibleError } from './utils.js';
export class ViteDevServerAdapter {
    constructor(pluginName, config, server) {
        this.moduleGraph = createViteModuleGraphAdapter(pluginName);
        this.config = config;
        this.pluginName = pluginName;
        // watcher is not used in Farm vite plugin for now
        // it's only for compatibility
        // this.watcher = watch(config.root);
        this.watcher = server.watcher.getInternalWatcher();
        this.middlewareCallbacks = [];
        this.middlewares = new Proxy({
            use: (...args) => {
                if (args.length === 2 &&
                    typeof args[0] === 'string' &&
                    typeof args[1] === 'function') {
                    this.middlewareCallbacks.push((req, res, next) => {
                        const [url, cb] = args;
                        if (req.url.startsWith(url)) {
                            cb(req, res, next);
                        }
                    });
                }
                else if (args.length === 1 && typeof args[0] === 'function') {
                    this.middlewareCallbacks.push(args[0]);
                }
            }
        }, {
            get(target, key) {
                if (key === 'use') {
                    return target[key];
                }
                throwIncompatibleError(pluginName, 'viteDevServer.middlewares', ['use'], key);
            }
        });
        this.ws = server.ws;
        this.httpServer = server.server;
    }
}
export class ViteModuleGraphAdapter {
    constructor(pluginName) {
        // context will be set in buildStart hook
        this.context = undefined;
        this.pluginName = pluginName;
    }
    getModulesByFile(file) {
        const raw = this.context.viteGetModulesByFile(file);
        return raw.map((item) => {
            return proxyViteModuleNode(item, this.pluginName, this.context);
        });
    }
    getModuleById(id) {
        const raw = this.context.viteGetModuleById(id);
        if (raw) {
            return proxyViteModuleNode(raw, this.pluginName, this.context);
        }
    }
    async getModuleByUrl(url) {
        if (url.startsWith('/')) {
            url = url.slice(1);
            const raw = this.context.viteGetModuleById(url);
            if (raw) {
                return proxyViteModuleNode(raw, this.pluginName, this.context);
            }
        }
    }
    invalidateModule() {
        /** does thing for now, only for compatibility */
    }
}
function proxyViteModuleNode(node, pluginName, context) {
    const proxy = new Proxy(node, {
        get(target, key) {
            if (key === 'importers') {
                return context.viteGetImporters(target.id);
            }
            const allowedKeys = ['url', 'id', 'file', 'type'];
            if (allowedKeys.includes(String(key))) {
                return target[key];
            }
            throwIncompatibleError(pluginName, 'viteModuleNode', allowedKeys, key);
        }
    });
    return proxy;
}
export function createViteDevServerAdapter(pluginName, config, server) {
    const proxy = new Proxy(new ViteDevServerAdapter(pluginName, config, server), {
        get(target, key) {
            const allowedKeys = [
                'moduleGraph',
                'config',
                'watcher',
                'middlewares',
                'middlewareCallbacks',
                'ws',
                'httpServer'
            ];
            if (allowedKeys.includes(String(key))) {
                return target[key];
            }
            throwIncompatibleError(pluginName, 'viteDevServer', allowedKeys, key);
        }
    });
    return proxy;
}
export function createViteModuleGraphAdapter(pluginName) {
    const proxy = new Proxy(new ViteModuleGraphAdapter(pluginName), {
        get(target, key) {
            const allowedKeys = [
                'getModulesByFile',
                'getModuleById',
                'getModuleByUrl',
                'invalidateModule'
            ];
            const ownkeys = Reflect.ownKeys(target);
            if (allowedKeys.includes(String(key)) || ownkeys.includes(key)) {
                return target[key];
            }
            throwIncompatibleError(pluginName, 'viteModuleGraph', allowedKeys, key);
        },
        set(target, p, newValue, _receiver) {
            if (p === 'context') {
                target.context = newValue;
                return true;
            }
            throwIncompatibleError(pluginName, 'viteModuleGraph', ['context'], p);
        }
    });
    return proxy;
}
//# sourceMappingURL=vite-server-adapter.js.map