"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
const protocol_1 = __importDefault(require("../../protocol"));
const parser_1 = __importDefault(require("../../parser"));
const command_1 = __importDefault(require("../../command"));
const RE_ERROR = /^Error: (.*)$/;
const EXTRA_TYPES = {
    string: 's',
    null: 'sn',
    bool: 'z',
    int: 'i',
    long: 'l',
    float: 'l',
    uri: 'u',
    component: 'cn',
};
class StartActivityCommand extends command_1.default {
    execute(options) {
        const args = this._intentArgs(options);
        if (options.debug) {
            args.push('-D');
        }
        if (options.wait) {
            args.push('-W');
        }
        if (options.user || options.user === 0) {
            args.push('--user', this._escape(options.user));
        }
        return this._run('start', args);
    }
    _run(command, args) {
        this._send(`shell:am ${command} ${args.join(' ')}`);
        return this.parser.readAscii(4).then((reply) => {
            switch (reply) {
                case protocol_1.default.OKAY:
                    return this.parser
                        .searchLine(RE_ERROR)
                        .finally(() => {
                        return this.parser.end();
                    })
                        .then(function (match) {
                        throw new Error(match[1]);
                    })
                        .catch(parser_1.default.PrematureEOFError, function () {
                        return true;
                    });
                case protocol_1.default.FAIL:
                    return this.parser.readError();
                default:
                    return this.parser.unexpected(reply, 'OKAY or FAIL');
            }
        });
    }
    _intentArgs(options) {
        const args = [];
        if (options.extras) {
            args.push(...this._formatExtras(options.extras));
        }
        if (options.action) {
            args.push('-a', this._escape(options.action));
        }
        if (options.data) {
            args.push('-d', this._escape(options.data));
        }
        if (options.mimeType) {
            args.push('-t', this._escape(options.mimeType));
        }
        if (options.category) {
            if (Array.isArray(options.category)) {
                options.category.forEach((category) => {
                    return args.push('-c', this._escape(category));
                });
            }
            else {
                args.push('-c', this._escape(options.category));
            }
        }
        if (options.component) {
            args.push('-n', this._escape(options.component));
        }
        if (options.flags) {
            args.push('-f', this._escape(options.flags));
        }
        return args;
    }
    // StartActivityOptions['extras']
    _formatExtras(extras) {
        if (!extras) {
            return [];
        }
        if (Array.isArray(extras)) {
            return extras.reduce((all, extra) => {
                return all.concat(this._formatLongExtra(extra));
            }, []);
        }
        else {
            return Object.keys(extras).reduce((all, key) => {
                return all.concat(this._formatShortExtra(key, extras[key]));
            }, []);
        }
    }
    _formatShortExtra(key, value) {
        let sugared = {
            key: key,
            type: '',
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            value: undefined,
        };
        if (value === null) {
            sugared.type = 'null';
        }
        else if (Array.isArray(value)) {
            throw new Error(`Refusing to format array value '${key}' using short syntax; empty array would cause unpredictable results due to unknown type. Please use long syntax instead.`);
        }
        else {
            switch (typeof value) {
                case 'string':
                    sugared.type = 'string';
                    sugared.value = value;
                    break;
                case 'boolean':
                    sugared.type = 'bool';
                    sugared.value = value;
                    break;
                case 'number':
                    sugared.type = 'int';
                    sugared.value = value;
                    break;
                case 'object':
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    sugared = value;
                    sugared.key = key;
            }
        }
        return this._formatLongExtra(sugared);
    }
    _formatLongExtra(extra) {
        const args = [];
        if (!extra.type) {
            extra.type = 'string';
        }
        const type = EXTRA_TYPES[extra.type];
        if (!type) {
            throw new Error(`Unsupported type '${extra.type}' for extra '${extra.key}'`);
        }
        if (extra.type === 'null') {
            args.push(`--e${type}`);
            args.push(this._escape(extra.key));
        }
        else if (Array.isArray(extra.value)) {
            args.push(`--e${type}a`);
            args.push(this._escape(extra.key));
            args.push(this._escape(extra.value.join(',')));
        }
        else {
            args.push(`--e${type}`);
            args.push(this._escape(extra.key));
            args.push(this._escape(extra.value));
        }
        return args;
    }
}
module.exports = StartActivityCommand;
//# sourceMappingURL=startactivity.js.map