var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/*
 * Copyright 2019 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import * as assert from 'assert';
import { readFileSync, unlink } from 'fs';
import { fileSync as tmpFile } from 'tmp';
import { promisify } from 'util';
import { Common, CLI, Keys, ReplExpect, Selectors } from '@kui-shell/test';
/** helpful selectors */
const rows = (N) => Selectors.xtermRows(N);
const firstRow = (N) => `${rows(N)} > div:first-child`;
const lastRow = (N) => `${rows(N)} > div:last-child`;
describe(`xterm copy paste ${process.env.MOCHA_RUN_TARGET || ''}`, function () {
    before(Common.before(this));
    after(Common.after(this));
    const emittedText = 'roadhouse';
    it(`should echo ${emittedText}`, () => __awaiter(this, void 0, void 0, function* () {
        try {
            const res = yield CLI.command(`echo ${emittedText}`, this.app);
            // wait for the output to appear
            yield this.app.client.waitForExist(rows(res.count));
            let idx = 0;
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const actualText = yield this.app.client.getText(rows(res.count));
                if (++idx > 5) {
                    console.error('still waiting for emitted text', actualText, res.count);
                }
                return actualText === emittedText;
            }), CLI.waitTimeout);
            console.log('now should copy from xterm output and paste outside of xterm');
            yield this.app.client.doubleClick(firstRow(res.count));
            yield this.app.client.execute(() => document.execCommand('copy'));
            yield this.app.client.waitForExist(Selectors.CURRENT_PROMPT_BLOCK);
            yield this.app.client.click(Selectors.CURRENT_PROMPT_BLOCK);
            yield this.app.client.execute(() => document.execCommand('paste'));
            idx = 0;
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const [actualValue, expectedValue] = yield Promise.all([
                    this.app.client.getValue(Selectors.CURRENT_PROMPT),
                    this.app.client.getText(rows(res.count))
                ]);
                if (++idx > 5) {
                    console.error(`still waiting for text actualValue=${actualValue} expectedValue=${expectedValue}`);
                }
                return expectedValue === actualValue;
            }), CLI.waitTimeout);
        }
        catch (err) {
            return Common.oops(this, true)(err);
        }
    }));
    it('should copy outside of xterm and paste inside of xterm', () => __awaiter(this, void 0, void 0, function* () {
        const text = 'hello';
        const file = tmpFile();
        try {
            // clear things out
            console.error('CP1');
            yield Common.refresh(this);
            // emit some characters to the current prompt
            console.error('CP2');
            yield this.app.client.keys(text);
            // wait for those characters to appear in the prompt
            console.error('CP3');
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const actualText = yield this.app.client.getValue(Selectors.CURRENT_PROMPT);
                return actualText === text;
            }), CLI.waitTimeout);
            // copy the content of the current prompt
            console.error('CP4');
            yield this.app.client.doubleClick(Selectors.CURRENT_PROMPT);
            console.error('CP5');
            yield this.app.client.execute(() => document.execCommand('copy'));
            // cancel out the current prompt so we can execute vi
            console.error('CP6');
            yield this.app.client.keys(Keys.ctrlC);
            // open vi, so we have an xterm to receive a paste event
            // the last true means don't try to use the copy-paste optimization
            console.error('CP7');
            const res = yield CLI.command(`vim -i NONE ${file.name}`, this.app, false, true);
            // wait for vi to come up in alt buffer mode
            console.error('CP8');
            yield this.app.client.waitForExist(Selectors.ALT_BUFFER_N(1));
            // enter insert mode, and wait for INSERT to appear at the bottom
            console.error('CP9');
            yield this.app.client.keys('i');
            console.error('CP10');
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const txt = yield this.app.client.getText(lastRow(res.count));
                return /INSERT/i.test(txt);
            }), CLI.waitTimeout);
            // now paste into the xterm vi
            console.error('CP11');
            yield this.app.client.execute(() => document.execCommand('paste'));
            // escape then :wq
            let idx = 0;
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                console.error(`CP12.${idx}`);
                yield this.app.client.keys(Keys.ESCAPE);
                console.error(`CP13.${idx}`);
                const txt = yield this.app.client.getText(lastRow(res.count));
                if (++idx > 5) {
                    console.error(`still waiting for text actualValue=${txt} whereas length should be zero`);
                }
                return !/INSERT/i.test(txt);
            }), CLI.waitTimeout);
            console.error('CP14');
            yield this.app.client.keys(':wq');
            console.error('CP15');
            yield this.app.client.keys(Keys.ENTER);
            console.error('CP16');
            yield ReplExpect.blank(res);
            console.error('CP17');
            yield CLI.command(`cat ${file.name}`, this.app).then(ReplExpect.okWithPtyOutputEventually(text));
            const contents = readFileSync(file.name).toString();
            assert.strictEqual(contents.replace(/[\n\r]$/, ''), text);
            console.error('CP18');
        }
        catch (err) {
            return Common.oops(this, true)(err);
        }
        finally {
            // DO NOT return a promise here; see https://github.com/mochajs/mocha/issues/3555
            promisify(unlink)(file.name);
        }
    }));
});
//# sourceMappingURL=pty-copy-paste.js.map