'use strict'
CACHE.router = {};

var Router ={
    goAsset:function(path,req,res){
        let assetFile = Core.Path.Asset+path;
        FILE.stat(assetFile,function(err,status){
            if(err || !status.isFile()){
                Router._error('No such file ['+path+']',res);
            }else{
                STATIC.load(assetFile,req,res);
            }
        });
    },
    goHandler:function(path,req,res){
        let handlerFile = Core.Path.Handler + path + '.js';
        let pathArr = path.split('/');
        let method = pathArr.pop();

        if(!method) method = 'index';

        if(CACHE.router[handlerFile]){
            Router.runHandler(handlerFile,method,req,res);
            return;
        }
        FILE.stat(handlerFile,function(err,status){
            if(err || !status.isFile()){
                if(pathArr.length<=1) return Router._error('No such handler ['+handlerFile+']',res);
                handlerFile = Core.Path.Handler + pathArr.join('/') + '.js';
                FILE.stat(handlerFile,function(err,status){
                    if(err || !status.isFile()){
                        Router._error('No such handler ['+handlerFile+']',res);
                    }else{
                        Router.runHandler(handlerFile,method,req,res);
                    }
                });
            }else{
                Router.runHandler(handlerFile,method,req,res);
            }
        });
    },
    runHandler:function(handlerFile,method,req,res){
        let handler;
        try {
            handler = require(handlerFile);
        }catch(e){
            Router._error(e.stack,res);
        }

        let newHandlerClass = Object.assign({
            'Request'  : req,
            'Response' : res,
            'COOKIE'   : req._Cookie,
            'GET'      : req._GET,
            'POST'     : req._POST,
            'UPLOAD'   : req._UPLOAD
        },handler);
        
        if(!CACHE.router[handlerFile]){ CACHE.router[handlerFile] = true;}

        if(newHandlerClass.hasOwnProperty(method) && typeof newHandlerClass[method]==='function'){
            let noBypass = true;
            if(newHandlerClass.hasOwnProperty('__construct') && typeof newHandlerClass['__construct']==='function') noBypass = newHandlerClass['__construct']();
            if(noBypass || noBypass===undefined) newHandlerClass[method]();
        }else{
            Router._error('Handler ['+handlerFile+'] no such method "'+method+'"',res);
        }
    },
    _error:function(log,res){
        LOGGER.error(log);
        res.writeHead(404, {'Content-Type': 'text/html'});
        res.end('404');
    }
};

module.exports = function(req,res){
    let URI       = req.url=='/'?'/index':req.url;
    let URLParse  = URL.parse(URI,true);
    let URLArr    = URLParse.pathname.split('/');
    let enterURI  = String(URLArr[1])==''?'index':String(URLArr[1]);
    let isAsset   = enterURI == Config.Asset.asset_path;

    req._GET = URLParse.query;
    if(isAsset){
        let assetPath = URLArr.join('/').replace('/'+Config.Asset.asset_path,'');
        Router.goAsset(assetPath,req,res);
        return;
    }
    req._Cookie = {};
    req.headers.cookie && req.headers.cookie.split(';').forEach(function(Cookie){
        let parts = Cookie.split('=');
        let key   = parts[0].trim();
        let value = (parts[1]||'').trim();
        if(parts.length>2){
            parts = parts.shift();
            value = parts.join('=').trim();
        }
        req._Cookie[key] = value;
    });
    Router.goHandler(URLParse.pathname,req,res);
    return this;
};