"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const static_1 = require("@angular-devkit/schematics/src/tree/static");
const index_1 = require("../index");
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const fs_1 = require("fs");
const rxjs_1 = require("rxjs");
const child_process_1 = require("child_process");
const ionic_1 = require("ionic");
const xml_editor_1 = require("../xml-editor");
// import { CordovaCommand } from 'ionic/commands/cordova/base';
function getTsPathConfigFromProject(tree, projectName) {
    const project = index_1.getAngularProject(tree, {
        project: projectName
    });
    let tsConfigPath = project['architect']['build']['options']['tsConfig'];
    if (!tsConfigPath) {
        throw new schematics_1.SchematicsException(`Cannot find tsConfig path`);
    }
    return tsConfigPath;
}
exports.getTsPathConfigFromProject = getTsPathConfigFromProject;
function updateJsonFile(host, path, callback) {
    const source = host.read(path);
    if (source) {
        const sourceText = source.toString('utf-8');
        const json = core_1.parseJson(sourceText, core_1.JsonParseMode.Loose);
        callback(json);
        host.overwrite(path, JSON.stringify(json, null, 2));
    }
    return host;
}
exports.updateJsonFile = updateJsonFile;
function getFileContentFromPath(path) {
    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) {
    let fileContent = tree.read(path);
    if (!fileContent) {
        throw new schematics_1.SchematicsException(`${path} file is empty (it should be a valid XML file), ${fileContent}`);
    }
    let xmlEditor = new xml_editor_1.XmlEditor(fileContent.toString());
    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;
function addRouteInConfig(route, tree) {
    index_1.updateAppConfig(tree, (appConfig) => {
        // TODO 
        // if (!appConfig.app.routes.find(r => route.path === r.path)){
        //     appConfig.app.routes.push(route);
        // }
    });
}
exports.addRouteInConfig = addRouteInConfig;
function ionicCommandFactory(cmdFactory) {
    return __awaiter(this, void 0, void 0, function* () {
        let pargv = process.argv.slice(2);
        let executor = yield ionic_1.loadExecutor(yield ionic_1.generateContext(), pargv);
        const namespace = executor.namespace;
        return {
            executor: executor,
            cmd: cmdFactory(namespace)
        };
    });
}
exports.ionicCommandFactory = ionicCommandFactory;
function runIonicCommand(cmdFactory, cmdinputs = [], cmdoptions = {}) {
    return __awaiter(this, void 0, void 0, function* () {
        // const deps: { env: IonicEnvironment; project?: IProject; } = {
        //     env: null as any,
        //     project: null as any
        // }
        let { cmd, executor } = yield ionicCommandFactory(cmdFactory);
        let env = process.env;
        let location = {
            args: [],
            obj: null,
            path: null,
        }; // TODO
        let commandInfo = { location, env, executor };
        return yield 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) {
    let myTree = tree;
    if (!myTree._base) {
        throw new schematics_1.SchematicsException('Cannot get real path for this tree. API changed ?');
    }
    let scope = tree.root.scope;
    let root = myTree._base._backend._root;
    // console.log('myTree', myTree);
    let 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);
    let fullPath = `${root}/${relativePath}/${file}`;
    console.log('fullPath', fullPath);
    let 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