import { USER_PROCESSOR } from '@sentio/runtime';
import { AccountConfig, ContractConfig, HandlerType } from '@sentio/protos';
import { IotaProcessorState } from './iota-processor.js';
import { IotaAccountProcessorState, IotaAddressProcessor } from './iota-object-processor.js';
import { initCoinList } from './ext/coin.js';
import { SuiChainId } from '@sentio/chain';
import { IotaAccountProcessorTemplateState } from './iota-object-processor-template.js';
import { IotaNetwork } from './network.js';
import { IotaContext } from './context.js';
export class IotaPluginPart {
    handlerRegister;
    partitionManager;
    constructor(handlerRegister, partitionManager) {
        this.handlerRegister = handlerRegister;
        this.partitionManager = partitionManager;
    }
    async start(request) {
        await initCoinList();
        console.log('total instances:', request.templateInstances.length);
        const allowedChainIds = new Set([SuiChainId.IOTA_MAINNET, SuiChainId.IOTA_TESTNET]);
        for (const instance of request.templateInstances) {
            if (!allowedChainIds.has(instance.contract?.chainId || '')) {
                continue;
            }
            console.log('start template instance', instance.templateId);
            const template = IotaAccountProcessorTemplateState.INSTANCE.getValues()[instance.templateId];
            template.startInstance({
                address: instance.contract?.address || '',
                objectId: instance.contract?.address || '',
                network: instance.contract?.chainId || IotaNetwork.MAIN_NET,
                startCheckpoint: instance.startBlock || 0n,
                endCheckpoint: instance.endBlock || 0n,
                baseLabels: instance.baseLabels
            }, NoopContext);
        }
    }
    async init(config) {
        for (const state of [IotaProcessorState.INSTANCE, IotaAccountProcessorState.INSTANCE]) {
            for (const suiProcessor of state.getValues()) {
                config.chainIds.push(suiProcessor.config.network);
            }
        }
    }
    async configure(config, forChainId) {
        // this.handlerRegister.clear(forChainId as any)
        for (const suiProcessor of IotaProcessorState.INSTANCE.getValues()) {
            const chainId = suiProcessor.config.network;
            if (forChainId !== undefined && forChainId !== chainId.toString()) {
                continue;
            }
            const contractConfig = ContractConfig.fromPartial({
                transactionConfig: [],
                processorType: USER_PROCESSOR,
                contract: {
                    name: suiProcessor.moduleName,
                    chainId: suiProcessor.config.network,
                    address: suiProcessor.config.address,
                    abi: ''
                },
                startBlock: suiProcessor.config.startCheckpoint,
                endBlock: suiProcessor.config.endCheckpoint
            });
            for (const handler of suiProcessor.eventHandlers) {
                const handlerId = this.handlerRegister.register(handler.handler, chainId);
                this.partitionManager.registerPartitionHandler(HandlerType.SUI_EVENT, handlerId, handler.partitionHandler);
                const eventHandlerConfig = {
                    filters: handler.filters.map((f) => {
                        return {
                            type: f.type,
                            account: f.account || '',
                            eventAccount: f.eventAccount || ''
                        };
                    }),
                    fetchConfig: handler.fetchConfig,
                    handlerId,
                    handlerName: handler.handlerName
                };
                contractConfig.moveEventConfigs.push(eventHandlerConfig);
            }
            for (const handler of suiProcessor.callHandlers) {
                const handlerId = this.handlerRegister.register(handler.handler, chainId);
                this.partitionManager.registerPartitionHandler(HandlerType.SUI_CALL, handlerId, handler.partitionHandler);
                const functionHandlerConfig = {
                    filters: handler.filters.map((filter) => {
                        return {
                            function: filter.function,
                            typeArguments: filter.typeArguments || [],
                            withTypeArguments: !!filter.typeArguments,
                            includeFailed: filter.includeFailed || false,
                            publicKeyPrefix: filter.publicKeyPrefix || '',
                            fromAndToAddress: filter.fromAndToAddress
                        };
                    }),
                    fetchConfig: handler.fetchConfig,
                    handlerId,
                    handlerName: handler.handlerName
                };
                contractConfig.moveCallConfigs.push(functionHandlerConfig);
            }
            // deprecated, use objectType processor instead
            for (const handler of suiProcessor.objectChangeHandlers) {
                const handlerId = this.handlerRegister.register(handler.handler, chainId);
                const objectChangeHandler = {
                    types: typeof handler.type === 'string' ? [handler.type] : handler.type,
                    handlerId,
                    handlerName: handler.handlerName,
                    includeDeleted: false
                };
                contractConfig.moveResourceChangeConfigs.push(objectChangeHandler);
            }
            config.contractConfigs.push(contractConfig);
        }
        for (const processor of IotaAccountProcessorState.INSTANCE.getValues()) {
            const chainId = processor.getChainId();
            if (forChainId !== undefined && forChainId !== chainId.toString()) {
                continue;
            }
            const accountConfig = AccountConfig.fromPartial({
                address: processor.config.address,
                chainId: processor.getChainId(),
                startBlock: processor.config.startCheckpoint, // TODO maybe use another field
                endBlock: processor.config.endCheckpoint
            });
            for (const handler of processor.objectChangeHandlers) {
                const handlerId = this.handlerRegister.register(handler.handler, chainId);
                const objectChangeHandler = {
                    types: typeof handler.type === 'string' ? [handler.type] : handler.type,
                    handlerId,
                    handlerName: handler.handlerName,
                    includeDeleted: false
                };
                accountConfig.moveResourceChangeConfigs.push(objectChangeHandler);
            }
            for (const handler of processor.objectHandlers) {
                const handlerId = this.handlerRegister.register(handler.handler, chainId);
                accountConfig.moveIntervalConfigs.push({
                    intervalConfig: {
                        handlerId: handlerId,
                        handlerName: handler.handlerName,
                        minutes: 0,
                        minutesInterval: handler.timeIntervalInMinutes,
                        slot: 0,
                        slotInterval: handler.checkPointInterval,
                        fetchConfig: undefined
                    },
                    type: handler.type || '',
                    ownerType: processor.ownerType,
                    resourceFetchConfig: handler.fetchConfig,
                    fetchConfig: undefined
                });
            }
            if (processor instanceof IotaAddressProcessor) {
                for (const handler of processor.callHandlers) {
                    const handlerId = this.handlerRegister.register(handler.handler, chainId);
                    const functionHandlerConfig = {
                        filters: handler.filters.map((filter) => {
                            return {
                                function: filter.function,
                                typeArguments: filter.typeArguments || [],
                                withTypeArguments: !!filter.typeArguments,
                                includeFailed: filter.includeFailed || false,
                                publicKeyPrefix: filter.publicKeyPrefix || '',
                                fromAndToAddress: filter.fromAndToAddress
                            };
                        }),
                        fetchConfig: handler.fetchConfig,
                        handlerId,
                        handlerName: handler.handlerName
                    };
                    accountConfig.moveCallConfigs.push(functionHandlerConfig);
                }
            }
            config.accountConfigs.push(accountConfig);
        }
    }
}
const NoopContext = new IotaContext('', SuiChainId.IOTA_MAINNET, '', new Date(), 0n, {}, 0, {});
//# sourceMappingURL=iota-plugin-part.js.map