import * as OS from 'os';
import * as NET from 'net';
import * as Path from 'path';
import * as FS from 'fs';
import * as Rimraf from 'rimraf';
import * as ChildProcess from 'child_process';

export namespace ACUtils {
    export const respath: string = Path.join(Path.resolve(__dirname, '../'), 'res');
    export function mkdirs(path: string): boolean {
        if (FS.existsSync(path)) {
            return true;
        } else {
            if (ACUtils.mkdirs(Path.dirname(path))) {
                FS.mkdirSync(path);
                return true;
            }
        }
        return false;
    }
    export function rmdirs(path: string): void {
        if( FS.existsSync(path) ) {
            Rimraf.sync(path);
        }
    }
    export function dash2hump(text: string): string {
        var arr = text.split('-');
        for(var i=1;i<arr.length;i++){
            arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
        }
        return arr.join('');
    }
    export function dash2hump4style(style: string): string {
        
        return style;
    }
    export function convert2path(text: string): string {
        let result: string = text;
        result = result.split('.').join('/');
        result = result.split('[').join('/');
        result = result.split(']').join('');
        result = result.trim();
        if (result.lastIndexOf('/') === result.length - 1) {
            result = result.substr(0, result.length - 1);
        }
        result = `/${result}`;
        return result;
    }
    export function pickFuncParams(text: string): string {
        const matched = text.match(/\(([\s\S]*)\)/);
        return matched ? matched[1] : '';
    }
    export function pickBindEnvValue(text: string): string | undefined {
        const matched = text.trim().match(/falcon_env\(([\s\S]*)\)/);
        return matched ? matched[1].trim() : undefined;
    }
    export function spawn(cmd:string, params:ReadonlyArray<string>): Promise<ChildProcess.SpawnSyncReturns<string>> {
        const result = ChildProcess.spawnSync(cmd, params);
        if (result.error) {
            return Promise.reject(result.error);
        } else {
            return Promise.resolve(result);
        }
    }
    export function localPort(): Promise<number> {
        return new Promise<number>((resolve, rejects)=>{
            const test: any = NET.createServer();
            test.listen(0);
            test.on('listening', () => {
                const port: number = test.address().port;
                test.close(()=>{
                    resolve(port);
                });
            });
        });
    }
    export function localIP(): string {
        const ifaces = OS.networkInterfaces();
        const ipv4s = new Array();
        Object.keys(ifaces).forEach(function (ifname) {
            ifaces[ifname].forEach(function (iface) {
                if ('IPv4' !== iface.family || iface.internal !== false) {
                    // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
                } else {
                    ipv4s.push({ name: ifname, info: iface });
                }
            });
        });
        let ip: string = '';
        ipv4s.forEach(element => {
            if ('en0' === element.name) {
                ip = element.info.address;
            }
        });
        return ip;
    }
    export function pickProjectPackage(path: string): any {
        return JSON.parse(FS.readFileSync(Path.join(path, 'package.json')).toString());
    }
    export function substring(text: string|undefined, startLine:number, startColumn:number, endLine:number, endColumn:number): string | undefined {
        if (text) {
            startLine -= 1;
            endLine -= 1;
            const lines = text.split('\n');
            let result = lines.slice(startLine, endLine > startLine ? endLine : startLine+1).join('\n');
            const endLength = lines[endLine].length - endColumn;
            result = result.substring(startColumn, result.length - endLength);
            return result;
        }
        return text;
    }
}