"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const static_1 = require("@angular-devkit/schematics/src/tree/static");
const cli_1 = require("@ionic/cli");
const child_process_1 = require("child_process");
const fs_1 = require("fs");
const rxjs_1 = require("rxjs");
const xml_editor_1 = require("../xml-editor");
const os_1 = require("os");
function convertXMLNodeToType(dotAccessor) {
    return dotAccessor.data;
}
exports.convertXMLNodeToType = convertXMLNodeToType;
async function updatePackageFile(host, callback) {
    return updateJsonFile(host, 'package.json', callback);
}
exports.updatePackageFile = updatePackageFile;
async function updateJsonFile(host, path, callback) {
    const source = host.read(path);
    if (source) {
        const sourceText = source.toString('utf-8').trim();
        // console.info(path, sourceText);
        let json;
        if (sourceText && sourceText.length > 0) {
            json = core_1.parseJson(sourceText, core_1.JsonParseMode.Loose);
        }
        json = await callback(json);
        host.overwrite(path, JSON.stringify(json, null, 2));
    }
    else {
        // console.warn(`no source: ${path}`)
        const json = await callback(undefined);
        host.create(path, JSON.stringify(json, null, 2));
        // console.warn(`Created file "${path}"`)
    }
    return host;
}
exports.updateJsonFile = updateJsonFile;
function getFileContentFromPath(path) {
    if (os_1.platform() !== 'win32') {
        path = path.replace(/\\\\/g, '/').replace(/\\/g, '/');
    }
    return fs_1.readFileSync(path);
}
exports.getFileContentFromPath = getFileContentFromPath;
function shellCommandSchematic({ command, args }) {
    return (host, _) => {
        return new rxjs_1.Observable(subscriber => {
            const child = child_process_1.spawn(command, args, { stdio: 'inherit', shell: true });
            child.on('error', error => {
                subscriber.error(error);
            });
            child.on('close', () => {
                subscriber.next(host);
                subscriber.complete();
            });
            return () => {
                child.kill();
            };
        });
    };
}
exports.shellCommandSchematic = shellCommandSchematic;
function updateXMLFile(tree, path, editFunction) {
    const xmlEditor = xml_editor_1.XmlEditor.fromTreeFile(tree, path);
    editFunction(xmlEditor);
    let xmlResult = xmlEditor.toXml();
    if (!xmlResult.startsWith('<?xml')) {
        xmlResult = "<?xml version='1.0' encoding='utf-8'?>\r\n" + xmlResult;
    }
    // console.info('Overwrite', path, xmlResult);
    tree.overwrite(path, xmlResult);
}
exports.updateXMLFile = updateXMLFile;
/**
* Run a schematic from a separate collection.
*
* @param collectionName The name of the collection that contains the schematic to run.
* @param schematicName The name of the schematic to run.
* @param options The options to pass as input to the RuleFactory.
*/
function externalPrivateSchematic(collectionName, schematicName, options, executionOptions) {
    return (input, context) => {
        const collection = context.engine.createCollection(collectionName);
        const schematic = collection.createSchematic(schematicName, true);
        const host = rxjs_1.of(static_1.branch(input));
        return schematic.call(options, host, context, executionOptions);
    };
}
exports.externalPrivateSchematic = externalPrivateSchematic;
async function ionicCommandFactory(cmdFactory) {
    const pargv = process.argv.slice(2);
    const executor = await cli_1.loadExecutor(await cli_1.generateContext(), pargv);
    const namespace = executor.namespace;
    return {
        executor: executor,
        cmd: cmdFactory(namespace)
    };
}
exports.ionicCommandFactory = ionicCommandFactory;
async function runIonicCommand(cmdFactory, cmdinputs = [], cmdoptions = {}) {
    // const deps: { env: IonicEnvironment; project?: IProject; } = {
    //     env: null as any,
    //     project: null as any
    // }
    const { cmd, executor } = await ionicCommandFactory(cmdFactory);
    const env = process.env;
    const location = {
        args: [],
        obj: null,
        path: null,
    }; // TODO
    const commandInfo = { location, env, executor };
    return await cmd.execute(cmdinputs, cmdoptions, commandInfo);
}
exports.runIonicCommand = runIonicCommand;
// export function runCordovaCommand(argList: string[]){
//   return this.runIonicCommand(
//     (namespace) => new PluginCommand(namespace), 
//     argList
//   )
// }
/**
 * TODO find another wait
 * does not work...
 */
function refreshTreeFromFile(tree, file) {
    const myTree = tree;
    if (!myTree._base) {
        throw new schematics_1.SchematicsException('Cannot get real path for this tree. API changed ?');
    }
    const scope = tree.root.scope;
    let root = myTree._base._backend._root;
    // console.log('myTree', myTree);
    const relativePath = scope.substr(1);
    root = root.replace('\\', '/');
    root = root.substr(1, 1) + ":/" + root.substr(2);
    console.log(root, relativePath, file);
    // let fullPath = resolve(root, relativePath, file);
    const fullPath = `${root}/${relativePath}/${file}`;
    console.log('fullPath', fullPath);
    const content = fs_1.readFileSync(fullPath);
    if (tree.exists(file)) {
        tree.overwrite(file, content);
    }
    else {
        tree.create(file, content);
    }
    console.log('NEW TREE CONFIG => ', tree.read(file));
}
exports.refreshTreeFromFile = refreshTreeFromFile;
//# sourceMappingURL=index.js.map