var express = require("express");
var app = express();
var autoroute = require("express-autoroute");
var http = require("http");
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var path = require("path");
var zxy = require('zxy-comm');
var _ = require('underscore');
var Promise = require('bluebird');
var fs = require('fs');
var extend = require('./extend');
var wechat = require('./wechat');

//运行Express
var runExpress = function (conf, middleware) {
    if (conf && conf.port) {
        app.configure(function () {
            app.set('port', conf.port);
            if (conf.static) {
                app.use(express.static(conf.static));
            }
            var defaultStaticPath = path.join(__dirname, '../frame structure demo/static');
            app.use('/express', express.static(defaultStaticPath));
            app.use(bodyParser.urlencoded({
                extended: true
            }));
            app.use(bodyParser.json());
            app.use(bodyParser.text({
                type: 'text/xml'
            }));
            app.use(bodyParser.text());
            app.use(methodOverride());
            app.use(function (req, res, next) {
                res.setHeader("Access-Control-Allow-Origin", "*");
                res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
                res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
                var _method = req.method;
                var _querystring = req.query;
                var _pid = process.pid;
                var _router = req.path;
                req._request = {
                    method: _method,
                    querystring: _querystring,
                    pid: _pid,
                    router: _router
                };
                if (isuploadrouter(req)) {
                    next();
                }
                else {
                    req.setEncoding('utf-8');
                    if (middleware && typeof middleware == 'function') {
                        middleware(req, res, function () {
                            output(req, next, _pid);
                        });
                    }
                    else {
                        output(req, next, _pid);
                    }
                }
            });
        });
        autoroute(app, { throwErrors: true });
        http.createServer(app).listen(app.get('port'), function () {
            var singleCoreProcess;
            if (process.argv) {
                if (process.argv.length) {
                    singleCoreProcess = process.argv[process.argv.length - 1].indexOf('-d') == 0 ? true : false
                }
                else {
                    singleCoreProcess = process.argv[0].indexOf('-d') == 0 ? true : false
                }
            }
            if (singleCoreProcess) {
                if (zxy.app.f_job) {
                    if (zxy.app.m_verify.isArray(zxy.app.f_job)) {
                        _.each(zxy.app.f_job, function (job) {
                            if (zxy.app.m_verify.isJson(job)) {
                                var job = new require('./comm/job').jobObj(job.conf, job.func, job.params, job.name);
                            }
                        });
                    }
                }
                var serverIp = zxy.app.m_obtain.getServerIP();
                console.info('a single core process[' + process.pid + '] listening on', serverIp, ':', app.get('port'));
            }
        });
        app.post('/zxy-upload', function (req, res, next) {
            extend.upload(req, res);
        });
        app.get('/zxy-download/:id', function (req, res, next) {
            extend.download(req, res);
        });
        app.get('/zxy-preview/:id', function (req, res, next) {
            extend.preview(req, res);
        });
        app.get('/zxy-attribute/:id', function (req, res, next) {
            extend.attribute(req, res);
        });
        app.get('/zxy-wechat/push', function (req, res, next) {
            var query = req.query;
            res.send(wechat.validateToken(query.signature, query.echostr, query.timestamp, query.nonce));
        });
        app.post('/zxy-wechat/push', function (req, res, next) {
			res.send("");
            //xml形式发送post
            //必填参数：ToUserName	开发者微信号
            //          FromUserName	发送方帐号（一个OpenID）
            //          CreateTime	消息创建时间 （整型）
            //          MsgType	消息类型
            //          MsgId	消息id，64位整型（event事件推送没有此参数，其余的普通消息推送都有此参数）
            //消息类型：text 文本消息                附加参数：Content 文本消息内容
            //          image 图片消息               附加参数：PicUrl 图片链接
            //                                                 MediaId 图片消息媒体id，可以调用多媒体文件下载接口拉取数据。
            //          voice 语音消息               附加参数：MediaId 语音消息媒体id，可以调用多媒体文件下载接口拉取数据。
            //                                                 Format 语音格式，如amr，speex等
            //                                                 Recognition 语音识别结果，UTF8编码（需要开启语音识别结果才会有此参数）
            //          video 视频消息               附加参数：MediaId 视频消息媒体id，可以调用多媒体文件下载接口拉取数据。
            //                                                 ThumbMediaId 视频消息缩略图的媒体id，可以调用多媒体文件下载接口拉取数据。
            //          shortvideo 小视频消息        附加参数：MediaId 视频消息媒体id，可以调用多媒体文件下载接口拉取数据。
            //                                                 ThumbMediaId 视频消息缩略图的媒体id，可以调用多媒体文件下载接口拉取数据。
            //          location 地理位置消息        附加参数：Location_X 地理位置维度
            //                                                 Location_Y 地理位置经度
            //                                                 Scale 地图缩放大小
            //                                                 Label 地理位置信息
            //          link 链接消息                附加参数：Title 消息标题
            //                                                 Description 消息描述
            //                                                 Url 消息链接
            //          event 事件                   附件参数：Event 事件类型      subscribe/unsubscribe 订阅/取消订阅
            //                                                                     subscribe                    EventKey 事件KEY值，qrscene_为前缀，后面为二维码的参数值
            //                                                                                                  Ticket 二维码的ticket，可用来换取二维码图片
            //                                                                     SCAN                         EventKey 事件KEY值，qrscene_为前缀，后面为二维码的参数值
            //                                                                                                  Ticket 二维码的ticket，可用来换取二维码图片
            //                                                                     LOCATION 上报地理位置事件    Latitude 地理位置纬度
            //                                                                                                  Longitude 地理位置经度
            //                                                                                                  Precision 地理位置精度
            //                                                                     CLICK 自定义菜单事件（点击菜单拉取消息时的事件推送）         EventKey 事件KEY值，与自定义菜单接口中KEY值对应
            //                                                                     VIEW 自定义菜单事件（点击菜单跳转链接时的事件推送）          EventKey 事件KEY值，设置的跳转URL
            req.setEncoding('utf-8');
                if (wechat.messageAvailability(req)) {
                    if (req.body && req.body != "{}" && req.body != {}) {
                        wechat.wechatXmlToJson(req.body, function (json) {
                            if (json) {
								if(json.MsgType.toLowerCase() == "event"){
									switch (json.Event.toLowerCase()) {
										//订阅（包括搜索和扫描二维码）
										case "subscribe":
											wechat.subscribe(json);
											break;
										//取消订阅
										case "unsubscribe":
											wechat.unsubscribe(json);
											break;
										//上报地理位置
										case "location":
											wechat.location(json);
											break;
									}
								}
                                if (zxy.app.f_processingBusiness && typeof zxy.app.f_processingBusiness == "function") {
                                    zxy.app.f_processingBusiness(json);
                                }
                            }
                            else {
								console.warn("参数解析异常");
                                res.send("参数解析异常");
                            }
                        });
                    }
                    else {
						console.warn("无效参数或无参数");
                    }
                }
                else {
					console.warn("有效性验证失败");
                }
        });
    }
}
exports.runExpress = runExpress;

function isuploadrouter(req) {
    if (req.path == '/zxy-upload' && req.method.toUpperCase() == "OPTIONS" ||
        req.path == '/zxy-upload' && req.method.toUpperCase() == "POST" ||
        req.path.StartWith('/zxy-download/') && req.method.toUpperCase() == "GET" ||
        req.path.StartWith('/zxy-preview/') && req.method.toUpperCase() == "GET" || 
		req.path.StartWith('/zxy-wechat/push')) {
        return true;
    }
    return false;
}

function l(req, pid) {
    setTimeout(function () {
        if (req.path != "/favicon.ico" && req.method.toLowerCase() != "options") {
            var method = req.method,
                path = req.path,
                params = req.params ? zxy.app.m_convert.objToStr(req.params) : "",
                query = req.query ? JSON.stringify(req.query) : "",
                body = req.body ? (zxy.app.m_verify.isJson(req.body) ? JSON.stringify(req.body) : req.body.toString()) : "",
                headers = req.headers ? JSON.stringify(req.headers) : "",
                clientip = zxy.app.m_obtain.getClientIP(req).replace('::ffff:', '');
            // params = params.split(',');
            // params[0] = params[0].substring(1);
            // params[params.length - 1] = params[params.length - 1].substring(0, params[1, params.length - 1].length - 1);
            console.info(method, "| ", path, "| ClientIP:", clientip, "| pid:", pid, "| params:", params, "| query:", query, "| body:", body, "| headers:", headers);
            var sql = "INSERT INTO zxy_api_log VALUES(UUID(),NOW(),@req_ip,@method,@path,@pid,@params,@query,@body,@headers)";
            zxy.app.m_mysql.run(sql, {
                req_ip: clientip,
                method: method,
                path: path,
                pid: pid,
                params: params,
                query: query,
                body: body,
                headers: headers
            });
        }
    }, 0);
}

function output(req, next, pid) {
    if (req.method.toLowerCase() === "post") {
        var _body = "";
        req.addListener("data", function (postDataChunk) {
            _body += postDataChunk;
        });
        req.addListener("end", function () {
            req.body = _body;
            next();
            l(req, pid);
        });
    }
    else {
        next();
        l(req, pid);
    }
}