
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { coalesce } from '../../../../base/common/arrays.js';
import { ThrottledDelayer } from '../../../../base/common/async.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { fromNow } from '../../../../base/common/date.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { basename } from '../../../../base/common/resources.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { IModelService } from '../../../../editor/common/services/model.service.js';
import { ITextModelService } from '../../../../editor/common/services/resolverService.service.js';
import { localize } from '../../../../nls.js';
import { registerAction2, Action2, MenuId } from '../../../../platform/actions/common/actions.js';
import { CodeDataTransfers } from '../../../../platform/dnd/browser/dnd.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { IChatWidgetService } from '../../chat/browser/chat.service.js';
import { picksWithPromiseFn } from '../../chat/browser/attachments/chatContextPickService.js';
import { IChatContextPickService } from '../../chat/browser/attachments/chatContextPickService.service.js';
import { ChatContextKeys } from '../../chat/common/actions/chatContextKeys.js';
import { ScmHistoryItemResolver } from '../../multiDiffEditor/browser/scmMultiDiffSourceResolver.js';
import { ISCMViewService, ISCMService } from '../common/scm.service.js';

var SCMHistoryItemContext_1, SCMHistoryItemChangeRangeContentProvider_1;
function extractSCMHistoryItemDropData(e) {
    if (!e.dataTransfer?.types.includes(CodeDataTransfers.SCM_HISTORY_ITEM)) {
        return undefined;
    }
    const data = e.dataTransfer?.getData(CodeDataTransfers.SCM_HISTORY_ITEM);
    if (!data) {
        return undefined;
    }
    return JSON.parse(data);
}
let SCMHistoryItemContextContribution = class SCMHistoryItemContextContribution extends Disposable {
    static {
        this.ID = "workbench.contrib.chat.scmHistoryItemContextContribution";
    }
    constructor(contextPickService, instantiationService, textModelResolverService) {
        super();
        this._store.add(
            contextPickService.registerChatContextItem(instantiationService.createInstance(SCMHistoryItemContext))
        );
        this._store.add(textModelResolverService.registerTextModelContentProvider(
            ScmHistoryItemResolver.scheme,
            instantiationService.createInstance(SCMHistoryItemContextContentProvider)
        ));
        this._store.add(textModelResolverService.registerTextModelContentProvider(
            SCMHistoryItemChangeRangeContentProvider.scheme,
            instantiationService.createInstance(SCMHistoryItemChangeRangeContentProvider)
        ));
    }
};
SCMHistoryItemContextContribution = ( __decorate([( __param(0, IChatContextPickService)), ( __param(1, IInstantiationService)), ( __param(2, ITextModelService))], SCMHistoryItemContextContribution));
let SCMHistoryItemContext = SCMHistoryItemContext_1 = class SCMHistoryItemContext {
    static asAttachment(provider, historyItem) {
        const historyItemParentId = historyItem.parentIds.length > 0 ? historyItem.parentIds[0] : undefined;
        const multiDiffSourceUri = ScmHistoryItemResolver.getMultiDiffSourceUri(provider, historyItem.id, historyItemParentId, historyItem.displayId);
        const attachmentName = `$(${Codicon.repo.id})\u00A0${provider.name}\u00A0$(${Codicon.gitCommit.id})\u00A0${historyItem.displayId ?? historyItem.id}`;
        return {
            id: historyItem.id,
            name: attachmentName,
            value: multiDiffSourceUri,
            historyItem: {
                ...historyItem,
                references: []
            },
            kind: "scmHistoryItem"
        };
    }
    constructor(_scmViewService) {
        this._scmViewService = _scmViewService;
        this.type = "pickerPick";
        this.label = ( localize(12293, "Source Control..."));
        this.icon = Codicon.gitCommit;
        this._delayer = ( new ThrottledDelayer(200));
    }
    isEnabled(widget) {
        const activeRepository = this._scmViewService.activeRepository.get();
        const supported = !!widget.attachmentCapabilities.supportsSourceControlAttachments;
        return activeRepository?.repository.provider.historyProvider.get() !== undefined && supported;
    }
    asPicker(_widget) {
        return {
            placeholder: ( localize(12294, "Select a change")),
            picks: picksWithPromiseFn((query, token) => {
                const filterText = query.trim() !== "" ? query.trim() : undefined;
                const activeRepository = this._scmViewService.activeRepository.get();
                const historyProvider = activeRepository?.repository.provider.historyProvider.get();
                if (!activeRepository || !historyProvider) {
                    return Promise.resolve([]);
                }
                const historyItemRefs = ( coalesce([
                    historyProvider.historyItemRef.get(),
                    historyProvider.historyItemRemoteRef.get(),
                    historyProvider.historyItemBaseRef.get()
                ]).map(ref => ref.id));
                return this._delayer.trigger(() => {
                    return historyProvider.provideHistoryItems({
                        historyItemRefs,
                        filterText,
                        limit: 100
                    }, token).then(historyItems => {
                        if (!historyItems) {
                            return [];
                        }
                        return (historyItems.map(historyItem => {
                            const details = [`${historyItem.displayId ?? historyItem.id}`];
                            if (historyItem.author) {
                                details.push(historyItem.author);
                            }
                            if (historyItem.statistics) {
                                details.push(`${historyItem.statistics.files} ${( localize(12295, "file(s)"))}`);
                            }
                            if (historyItem.timestamp) {
                                details.push(fromNow(historyItem.timestamp, true, true));
                            }
                            return {
                                iconClass: ThemeIcon.asClassName(Codicon.gitCommit),
                                label: historyItem.subject,
                                detail: details.join(`$(${Codicon.circleSmallFilled.id})`),
                                asAttachment: () => SCMHistoryItemContext_1.asAttachment(activeRepository.repository.provider, historyItem)
                            };
                        }));
                    });
                });
            })
        };
    }
};
SCMHistoryItemContext = SCMHistoryItemContext_1 = ( __decorate([( __param(0, ISCMViewService))], SCMHistoryItemContext));
let SCMHistoryItemContextContentProvider = class SCMHistoryItemContextContentProvider {
    constructor(_modelService, _scmService) {
        this._modelService = _modelService;
        this._scmService = _scmService;
    }
    async provideTextContent(resource) {
        const uriFields = ScmHistoryItemResolver.parseUri(resource);
        if (!uriFields) {
            return null;
        }
        const textModel = this._modelService.getModel(resource);
        if (textModel) {
            return textModel;
        }
        const {
            repositoryId,
            historyItemId
        } = uriFields;
        const repository = this._scmService.getRepository(repositoryId);
        const historyProvider = repository?.provider.historyProvider.get();
        if (!repository || !historyProvider) {
            return null;
        }
        const historyItemContext = await historyProvider.resolveHistoryItemChatContext(historyItemId);
        if (!historyItemContext) {
            return null;
        }
        return this._modelService.createModel(historyItemContext, null, resource, false);
    }
};
SCMHistoryItemContextContentProvider = ( __decorate([( __param(0, IModelService)), ( __param(1, ISCMService))], SCMHistoryItemContextContentProvider));
let SCMHistoryItemChangeRangeContentProvider = class SCMHistoryItemChangeRangeContentProvider {
    static {
        SCMHistoryItemChangeRangeContentProvider_1 = this;
    }
    static {
        this.scheme = "scm-history-item-change-range";
    }
    constructor(_modelService, _scmService) {
        this._modelService = _modelService;
        this._scmService = _scmService;
    }
    async provideTextContent(resource) {
        const uriFields = this._parseUri(resource);
        if (!uriFields) {
            return null;
        }
        const textModel = this._modelService.getModel(resource);
        if (textModel) {
            return textModel;
        }
        const {
            repositoryId,
            start,
            end
        } = uriFields;
        const repository = this._scmService.getRepository(repositoryId);
        const historyProvider = repository?.provider.historyProvider.get();
        if (!repository || !historyProvider) {
            return null;
        }
        const historyItemChangeRangeContext = await historyProvider.resolveHistoryItemChangeRangeChatContext(end, start, resource.path);
        if (!historyItemChangeRangeContext) {
            return null;
        }
        return this._modelService.createModel(historyItemChangeRangeContext, null, resource, false);
    }
    _parseUri(uri) {
        if (uri.scheme !== SCMHistoryItemChangeRangeContentProvider_1.scheme) {
            return undefined;
        }
        let query;
        try {
            query = JSON.parse(uri.query);
        } catch (e) {
            return undefined;
        }
        if (typeof query !== "object" || query === null) {
            return undefined;
        }
        const {
            repositoryId,
            start,
            end
        } = query;
        if (typeof repositoryId !== "string" || typeof start !== "string" || typeof end !== "string") {
            return undefined;
        }
        return {
            repositoryId,
            start,
            end
        };
    }
};
SCMHistoryItemChangeRangeContentProvider = SCMHistoryItemChangeRangeContentProvider_1 = ( __decorate([( __param(0, IModelService)), ( __param(1, ISCMService))], SCMHistoryItemChangeRangeContentProvider));
registerAction2(class extends Action2 {
    constructor() {
        super({
            id: "workbench.scm.action.graph.addHistoryItemToChat",
            title: ( localize(12296, "Add to Chat")),
            f1: false,
            menu: {
                id: MenuId.SCMHistoryItemContext,
                group: "z_chat",
                order: 1,
                when: ChatContextKeys.enabled
            }
        });
    }
    async run(accessor, provider, historyItem) {
        const chatWidgetService = accessor.get(IChatWidgetService);
        const widget = await chatWidgetService.revealWidget();
        if (!provider || !historyItem || !widget) {
            return;
        }
        widget.attachmentModel.addContext(SCMHistoryItemContext.asAttachment(provider, historyItem));
    }
});
registerAction2(class extends Action2 {
    constructor() {
        super({
            id: "workbench.scm.action.graph.summarizeHistoryItem",
            title: ( localize(12297, "Explain Changes")),
            f1: false,
            menu: {
                id: MenuId.SCMHistoryItemContext,
                group: "z_chat",
                order: 2,
                when: ChatContextKeys.enabled
            }
        });
    }
    async run(accessor, provider, historyItem) {
        const chatWidgetService = accessor.get(IChatWidgetService);
        const widget = await chatWidgetService.revealWidget();
        if (!provider || !historyItem || !widget) {
            return;
        }
        widget.attachmentModel.addContext(SCMHistoryItemContext.asAttachment(provider, historyItem));
        await widget.acceptInput("Summarize the attached history item");
    }
});
registerAction2(class extends Action2 {
    constructor() {
        super({
            id: "workbench.scm.action.graph.addHistoryItemChangeToChat",
            title: ( localize(12296, "Add to Chat")),
            f1: false,
            menu: {
                id: MenuId.SCMHistoryItemChangeContext,
                group: "z_chat",
                order: 1,
                when: ChatContextKeys.enabled
            }
        });
    }
    async run(accessor, historyItem, historyItemChange) {
        const chatWidgetService = accessor.get(IChatWidgetService);
        const widget = await chatWidgetService.revealWidget();
        if (!historyItem || !historyItemChange.modifiedUri || !widget) {
            return;
        }
        widget.attachmentModel.addContext({
            id: ( historyItemChange.uri.toString()),
            name: `${basename(historyItemChange.modifiedUri)}`,
            value: historyItemChange.modifiedUri,
            historyItem: historyItem,
            kind: "scmHistoryItemChange"
        });
    }
});

export { SCMHistoryItemChangeRangeContentProvider, SCMHistoryItemContextContribution, extractSCMHistoryItemDropData };
