import { __decorate, __param } from '../../../../../../../../external/tslib/tslib.es6.js';
import { $ as $$1 } from '../../../../../base/browser/dom.js';
import { CancellationTokenSource } from '../../../../../base/common/cancellation.js';
import { Emitter, Event } from '../../../../../base/common/event.js';
import { Disposable, toDisposable } from '../../../../../base/common/lifecycle.js';
import { Schemas } from '../../../../../base/common/network.js';
import { isEqual } from '../../../../../base/common/resources.js';
import { URI } from '../../../../../base/common/uri.js';
import { generateUuid } from '../../../../../base/common/uuid.js';
import { TextEdit } from '../../../../../editor/common/languages.js';
import { createTextBufferFactoryFromSnapshot } from '../../../../../editor/common/model/textModel.js';
import { IModelService } from '../../../../../editor/common/services/model.js';
import { DefaultModelSHA1Computer } from '../../../../../editor/common/services/modelService.js';
import { ITextModelService } from '../../../../../editor/common/services/resolverService.js';
import { localizeWithPath } from '../../../../../nls.js';
import { MenuId } from '../../../../../platform/actions/common/actions.js';
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
import { ResourcePool } from './chatCollections.js';
import { CodeCompareBlockPart } from '../codeBlockPart.js';
import { IChatService } from '../../common/chatService.service.js';
import { isResponseVM } from '../../common/chatViewModel.js';
const _moduleId = "vs/workbench/contrib/chat/browser/chatContentParts/chatTextEditContentPart";
const $ = $$1;
let ChatTextEditContentPart = class ChatTextEditContentPart extends Disposable {
    constructor(chatTextEdit, context, rendererOptions, diffEditorPool, currentWidth, textModelService, modelService, chatService) {
        super();
        this.textModelService = textModelService;
        this.modelService = modelService;
        this.chatService = chatService;
        this._onDidChangeHeight = this._register(( (new Emitter())));
        this.onDidChangeHeight = this._onDidChangeHeight.event;
        const element = context.element;
        if (rendererOptions.renderTextEditsAsSummary?.(chatTextEdit.uri)) {
            if (isResponseVM(element) && element.response.value.every(item => item.kind === 'textEditGroup')) {
                this.domNode = $('.interactive-edits-summary', undefined, !element.isComplete
                    ? ( localizeWithPath(_moduleId, 0, "Making changes..."))
                    : element.isCanceled
                        ? ( localizeWithPath(_moduleId, 1, "Making changes was aborted."))
                        : ( localizeWithPath(_moduleId, 2, "Made changes.")));
            }
            else {
                this.domNode = $('div');
            }
        }
        else {
            const cts = ( (new CancellationTokenSource()));
            let isDisposed = false;
            this._register(toDisposable(() => {
                isDisposed = true;
                cts.dispose(true);
            }));
            this.ref = this._register(diffEditorPool.get());
            this._register(this.ref.object.onDidChangeContentHeight(() => {
                this._onDidChangeHeight.fire();
            }));
            const data = {
                element,
                edit: chatTextEdit,
                diffData: (async () => {
                    const ref = await this.textModelService.createModelReference(chatTextEdit.uri);
                    if (isDisposed) {
                        ref.dispose();
                        return;
                    }
                    this._register(ref);
                    const original = ref.object.textEditorModel;
                    let originalSha1 = '';
                    if (chatTextEdit.state) {
                        originalSha1 = chatTextEdit.state.sha1;
                    }
                    else {
                        const sha1 = ( (new DefaultModelSHA1Computer()));
                        if (sha1.canComputeSHA1(original)) {
                            originalSha1 = sha1.computeSHA1(original);
                            chatTextEdit.state = { sha1: originalSha1, applied: 0 };
                        }
                    }
                    const modified = this.modelService.createModel(createTextBufferFactoryFromSnapshot(original.createSnapshot()), { languageId: original.getLanguageId(), onDidChange: Event.None }, ( (URI.from(
                        { scheme: Schemas.vscodeChatCodeBlock, path: original.uri.path, query: generateUuid() }
                    ))), false);
                    const modRef = await this.textModelService.createModelReference(modified.uri);
                    this._register(modRef);
                    const editGroups = [];
                    if (isResponseVM(element)) {
                        const chatModel = this.chatService.getSession(element.sessionId);
                        for (const request of chatModel.getRequests()) {
                            if (!request.response) {
                                continue;
                            }
                            for (const item of request.response.response.value) {
                                if (item.kind !== 'textEditGroup' || item.state?.applied || !isEqual(item.uri, chatTextEdit.uri)) {
                                    continue;
                                }
                                for (const group of item.edits) {
                                    const edits = ( (group.map(TextEdit.asEditOperation)));
                                    editGroups.push(edits);
                                }
                            }
                            if (request.response === element.model) {
                                break;
                            }
                        }
                    }
                    for (const edits of editGroups) {
                        modified.pushEditOperations(null, edits, () => null);
                    }
                    return {
                        modified,
                        original,
                        originalSha1
                    };
                })()
            };
            this.ref.object.render(data, currentWidth, cts.token);
            this.domNode = this.ref.object.element;
        }
    }
    layout(width) {
        this.ref?.object.layout(width);
    }
    hasSameContent(other) {
        return other.kind === 'textEditGroup';
    }
    addDisposable(disposable) {
        this._register(disposable);
    }
};
ChatTextEditContentPart = ( (__decorate([
    ( (__param(5, ITextModelService))),
    ( (__param(6, IModelService))),
    ( (__param(7, IChatService)))
], ChatTextEditContentPart)));
let DiffEditorPool = class DiffEditorPool extends Disposable {
    inUse() {
        return this._pool.inUse;
    }
    constructor(options, delegate, overflowWidgetsDomNode, instantiationService) {
        super();
        this._pool = this._register(( (new ResourcePool(() => {
            return instantiationService.createInstance(CodeCompareBlockPart, options, MenuId.ChatCompareBlock, delegate, overflowWidgetsDomNode);
        }))));
    }
    get() {
        const codeBlock = this._pool.get();
        let stale = false;
        return {
            object: codeBlock,
            isStale: () => stale,
            dispose: () => {
                codeBlock.reset();
                stale = true;
                this._pool.release(codeBlock);
            }
        };
    }
};
DiffEditorPool = ( (__decorate([
    ( (__param(3, IInstantiationService)))
], DiffEditorPool)));
export { ChatTextEditContentPart, DiffEditorPool };
