function platform (command, targets, opts) {
    // CB-10519 wrap function code into promise so throwing error
    // would result in promise rejection instead of uncaught exception
    return Promise.resolve().then(function () {
        var msg;
        var projectRoot = cordova_util.cdProjectRoot();
        var hooksRunner = new HooksRunner(projectRoot);

        if (arguments.length === 0) command = 'ls';

        if (targets && !(targets instanceof Array)) targets = [targets];

        // TODO: wouldn't update need a platform, too? what about save?
        if ((command === 'add' || command === 'rm' || command === 'remove') && (!targets || (targets instanceof Array && targets.length === 0))) {
            msg = 'You need to qualify `' + command + '` with one or more platforms!';
            return Promise.reject(new CordovaError(msg));
        }

        opts = opts || {};
        opts.platforms = targets;
        switch (command) {
        case 'add':
            return module.exports.add(hooksRunner, projectRoot, targets, opts);
        case 'rm':
        case 'remove':
            return module.exports.remove(hooksRunner, projectRoot, targets, opts);
        case 'update':
        case 'up':
            return module.exports.update(hooksRunner, projectRoot, targets, opts);
        case 'check':
            return module.exports.check(hooksRunner, projectRoot);
        default:
            return module.exports.list(hooksRunner, projectRoot, opts);
        }
    });
}