/*
 * 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.
 */
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());
    });
};
import { Common, CLI, Keys, ReplExpect, Selectors, SidecarExpect } from '@kui-shell/test';
import { createNS, allocateNS, deleteNS, typeSlowly, waitForGreen } from '@kui-shell/plugin-kubectl/tests/lib/k8s/utils';
import { readFileSync } from 'fs';
import { dirname, join } from 'path';
const ROOT = dirname(require.resolve('@kui-shell/plugin-kubectl/tests/package.json'));
const inputBuffer = readFileSync(join(ROOT, 'data/k8s/kubectl-exec.yaml'));
const inputEncoded = inputBuffer.toString('base64');
/** we have a custom vimrc, to make sure INSERT shows up */
// const vimrc = join(dirname(require.resolve('@kui-shell/plugin-bash-like/tests/data/marker.json')), 'vimrc')
/** sleep for N seconds */
function sleep(N) {
    return new Promise(resolve => setTimeout(resolve, N * 1000));
}
describe(`kubectl exec vi ${process.env.MOCHA_RUN_TARGET || ''}`, function () {
    before(Common.before(this));
    after(Common.after(this));
    const ns = createNS();
    allocateNS(this, ns);
    const podName = 'vim';
    it(`should create sample pod from URL`, () => {
        return CLI.command(`echo ${inputEncoded} | base64 --decode | kubectl create -f - -n ${ns}`, this.app)
            .then(ReplExpect.okWithPtyOutput(podName))
            .catch(Common.oops(this));
    });
    if (!process.env.USE_WATCH_PANE) {
        it(`should wait for the pod to come up`, () => {
            return CLI.command(`kubectl get pod ${podName} -n ${ns} -w`, this.app)
                .then(ReplExpect.okWithCustom({ selector: Selectors.BY_NAME(podName) }))
                .then(selector => waitForGreen(this.app, selector))
                .catch(Common.oops(this));
        });
    }
    else {
        it(`should wait for the pod to come up`, () => {
            return CLI.command(`kubectl get pod ${podName} -n ${ns} -w`, this.app)
                .then(() => __awaiter(this, void 0, void 0, function* () {
                yield this.app.client.waitForExist(Selectors.CURRENT_GRID_ONLINE_FOR_SPLIT(2, podName));
            }))
                .catch(Common.oops(this));
        });
    }
    it('should reload', () => Common.refresh(this));
    // needed to force the dom renderer for webpack/browser-based tests;
    // see ExecIntoPod; careful to place this after the refresh!!!
    Common.setDebugMode.bind(this)();
    /* it(`should copy the vimrc to the current container`, () => {
      return CLI
        .command(`kubectl cp ${vimrc} -n ${ns} ${ns}/${podName}:/root/.vimrc`, this.app)
        .then(ReplExpect.ok)
        .catch(Common.oops(this))
    }) */
    const filename = '/tmp/foo.txt';
    const typeThisText = 'hello there';
    it(`should use kubectl exec vi through pty`, () => __awaiter(this, void 0, void 0, function* () {
        try {
            yield CLI.command(`kubectl exec -it ${podName} -n ${ns} -- vim -i NONE ${filename}`, this.app).then(ReplExpect.justOK);
            const rows = `${Selectors.SIDECAR_TAB_CONTENT} .xterm-rows`;
            const focusArea = `${Selectors.SIDECAR_TAB_CONTENT} .xterm-helper-textarea`;
            const lastRowSelector = `${rows} > div:last-child`;
            const lastRow = () => __awaiter(this, void 0, void 0, function* () {
                return this.app.client.getText(lastRowSelector);
            });
            // wait for vi to come up
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                yield this.app.client.waitForExist(rows);
                return this.app.client.hasFocus(focusArea);
            }));
            sleep(3);
            // enter insert mode, and wait for INSERT to appear at the bottom
            let iter = 0;
            yield this.app.client.keys('i');
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const txt = yield lastRow();
                if (++iter > 5) {
                    console.error('kubectl exec vi still waiting for Insert mode', txt);
                }
                return /INSERT/i.test(txt);
            }));
            // type our input
            yield typeSlowly(this.app, typeThisText);
            // exit vi input mode
            iter = 0;
            yield this.app.client.keys(Keys.ESCAPE);
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                const txt = yield lastRow();
                if (++iter > 5) {
                    console.error('kubectl exec vi still waiting to exit insert mode', txt);
                }
                return !/INSERT/i.test(txt);
            }));
            // wait for vi to exit and the next prompt block to appear
            iter = 0;
            yield this.app.client.waitUntil(() => __awaiter(this, void 0, void 0, function* () {
                yield this.app.client.keys(Keys.ESCAPE);
                yield typeSlowly(this.app, `:wq${Keys.ENTER}`);
                try {
                    yield SidecarExpect.toolbarText({ type: 'error', text: 'closed', exact: false })(this.app);
                    return true;
                }
                catch (err) {
                    console.error(`hmm, the view has not yet indicated the pty has closed at iter ${iter++}`);
                    return false;
                }
            }));
        }
        catch (err) {
            yield Common.oops(this, true)(err);
        }
    }));
    it('should use kubectl exec to cat the file we just edited', () => __awaiter(this, void 0, void 0, function* () {
        return CLI.command(`kubectl exec ${podName} -n ${ns} -- cat ${filename}`, this.app)
            .then(ReplExpect.okWithString(typeThisText))
            .catch(Common.oops(this, true));
    }));
    deleteNS(this, ns);
});
//# sourceMappingURL=kubectl-exec-vi.js.map