/*
 * 用 http://localhost:端口 或 http://127.0.0.1:端口 连接这个服务器
 * 端口默认8000
 *
 * 从配置来判断是否进行smarty的编译，默认开启。
 * 要进行编译时，文件格式必须是（html|htm|tpl）,同时在文件目录里有网页同名的json文件。
 * 例如：文件目录存在index.html和index.json时，在浏览index.html时才会对里面的smarty代码进行编译。
 *
 * web.config.json
 * {
    //监听端口
    "port": "8000",
    //目录默认浏览的文件
    "default_page": "index.html",
    //目录默认浏览的文件格式
    "default_ext": "html",
    //静态文件存放的相对路径
    "relative_path": "wwwroot",
    //当文件不存在时是否显示目录的文件列表
    "is_show_path_file": false,
    //是否进行smarty编译
    "parse_smarty": true,
    //smarty左侧界定符
    "left_delimiter": "{{",
    //smarty右侧界定符
    "right_delimiter": "}}"
}
 * 
 */

var http = require( 'http' ); // Http服务器API
var path = require( 'path' ); // 目录的处理API
var fs = require( 'fs' ); // 用于处理本地文件
var readlineSync = require( '@fsteam/readline-sync' );
var JsonFile = require( 'sqp/jsonfile' );
var smarty = require( './smarty' );
var util = require( './util' ).obj;

var serverConfigJs = "../config/server.config";
var webConfigJson = '../config/web.config.json';
var mine = require( serverConfigJs ).mine;
var webConf = require( webConfigJson );

util.parseData = function( info ) {
    var res = readlineSync.question( info.info );
    var tmp = [];
    if ( !res ) {
        return "";
    }
    tmp.push( res );
    if ( info.type === "boolean" ) {
        if ( res === "y" ) {
            tmp.push( true );
        } else if ( res === "n" ) {
            tmp.push( false );
        } else {
            tmp.push( "" );
        }
    }
    if ( info.type === "number" ) {
        var n = +res;
        if ( ( n - n + 1 ) >= 0 ) {
            tmp.push( n );
        } else {
            tmp.push( "" );
        }
    }
    if ( info.type === "string" ) {
        tmp.push( res );
    } else {
        tmp.push( "" );
    }
    if ( tmp[ 1 ] === "" ) {
        if ( readlineSync.question( "您输入的内容有误！是否重新输入?（y/n）" ) === "y" ) {
            return util.parseData( info );
        }
        return "";
    }
    return tmp;
};

exports.build_cmd = [ {
    "info": "启动web服务",
    "cmd": "run"
}, {
    "info": "修改web服务的配置",
    "cmd": "edit"
} ];
exports.cmd = function() {
    exports[ util.select_cmd( exports.build_cmd ) ]();
};
exports.run = function() {
    //console.log(webConf.port);
    var server = new http.Server(); // 创建新的HTTP服务器
    server.listen( webConf.port ); // 监听端口

    // 使用on方法注册处理
    server.on( 'request', function( request, response ) { // 当有request请求的时候触发处理函数
        var hasExt = webConf.is_show_path_file; //是否列出目录里的文件，默认不显示
        var realPath = "";
        // 解析请求的URL
        var url = require( 'url' ).parse( request.url );
        var pathname = url.pathname;

        //对请求的路径进行解码，防止中文乱码
        pathname = decodeURI( pathname );

        //返回path路径文件扩展名
        var ext = path.extname( pathname );
        //如果路径中没有扩展名
        if ( ext === '' ) {
            //如果不是以/结尾的，加/并作301重定向
            if ( pathname.charAt( pathname.length - 1 ) != "/" ) {
                pathname += "/";
                var redirect = "http://" + request.headers.host + pathname;
                response.writeHead( 301, {
                    location: redirect
                } );
                response.end();
            }
            //添加默认的访问页面,但这个页面不一定存在,后面会处理
            pathname += webConf.default_page;
            hasExt = false; //标记默认页面是程序自动添加的
            ext = webConf.default_ext;
        } else {
            ext = ext.slice( 1 );
        }
        //获取对应文件的文档类型
        var contentType = mine[ ext ] || mine[ 'app' ];

        //获取资源文件的相对路径
        if ( webConf.relative_path ) {
            realPath = path.join( webConf.relative_path, pathname );
        } else {
            realPath = pathname;
        }

        //console.log(realPath);

        fs.exists( realPath, function( exists ) {
            if ( !exists ) {
                if ( hasExt ) {
                    //如果这个文件不是程序自动添加的，直接返回404
                    response.writeHead( 404, {
                        'Content-Type': mine[ 'txt' ]
                    } );

                    response.write( "<h1>404 Not Found</h1><br/>This request URL " + pathname + " was not found on this server." );
                    response.end();
                } else {
                    //如果文件是程序自动添加的且不存在，则表示用户希望访问的是该目录下的文件列表
                    var html = "<head><meta charset='utf-8'></head>";

                    try {
                        //用户访问目录
                        var filedir = realPath.substring( 0, realPath.lastIndexOf( '\\' ) );
                        //获取用户访问路径下的文件列表
                        var files = fs.readdirSync( filedir );
                        //将访问路径下的所以文件一一列举出来，并添加超链接，以便用户进一步访问
                        for ( var i in files ) {
                            var filename = files[ i ];
                            html += "<div><a href='" + filename + "'>" + filename + "</a></div>";
                        }
                    } catch ( e ) {
                        html += "<h1>您访问的目录不存在</h1>";
                    }
                    response.writeHead( 200, {
                        "content-type": mine[ 'htm' ]
                    } );
                    response.end( html );
                }
            } else {
                if ( contentType.indexOf( "UTF-8" ) > 0 ) {
                    var res = smarty.parse( realPath );
                    //console.log(res);
                    if ( res ) {
                        response.writeHead( 200, {
                            'Content-Type': contentType
                        } );

                        response.write( res );
                        response.end();
                    } else {
                        fs.readFile( realPath, 'utf8', function( err, file ) {
                            if ( err ) {
                                response.writeHead( 404, {
                                    'Content-Type': mine[ 'txt' ]
                                } );

                                response.write( "<h1>404 Not Found</h1><br/>" + err.message );
                                response.end();
                            } else {
                                response.writeHead( 200, {
                                    'Content-Type': contentType
                                } );

                                response.write( file, "utf8" );
                                response.end();
                            }
                        } );
                    }
                } else {
                    fs.readFile( realPath, "binary", function( err, file ) {
                        if ( err ) {
                            response.writeHead( 500, {
                                'Content-Type': mine[ 'txt' ]
                            } );
                            response.end( err );
                        } else {
                            response.writeHead( 200, {
                                'Content-Type': contentType
                            } );
                            response.write( file, "binary" );
                            response.end();
                        }
                    } );
                }
            }
        } );
    } );
    console.log( "Server runing at port: " + webConf.port + "." );
};
exports.edit = function() {
    var jsonfile = __dirname + "/" + webConfigJson;
    var jsondata = JsonFile.readFileSync( jsonfile, {
        encoding: 'utf-8'
    } );

    console.log( "\n当前web服务的配置为：" );
    console.log( jsondata );

    var key = readlineSync.question( "请输入您想修改的字段：" );

    if ( jsondata.hasOwnProperty( key ) ) {
        var info = require( serverConfigJs ).config[ key ];
        var res = util.parseData( info );
        if ( res !== "" ) {
            if ( res[ 1 ] !== "" ) {
                jsondata[ key ] = res[ 1 ];
            } else {
                return util.log( "修改结束！" );
            }
        } else {
            jsondata[ key ] = info.def;
        }
        JsonFile.writeFile( jsonfile, jsondata, function( err ) {
            if ( err ) {
                util.error( err );
            } else {
                util.log( "修改完成！" );
            }
        } );
    } else {
        util.error( "您输入的字段不存在！" );
    }
};
