
const config = require("../../config.js")
    ,Slack = require("../slack.js").Slack
    ,GoogleOAuth = require("../googleOAuth.js").GoogleOAuth
    ,FacebookOAuth = require("../facebookOAuth.js").FacebookOAuth
    ,slackManager = require("../slackManager.js").SlackManager
    ,accountManager = require("../models/accounts.js").accountManager
    ,accountConfigManager = require("../models/accountConfig.js").accountConfigManager
    ,sessionManager = require("../session.js").SessionManager
    ,templates = require('./_templates.js');

function checkTokens(service, req, res, cb) {
    switch (service) {
        case "slack":
            if (req.urlObj.queryTokens.code) {
                Slack.getUserId(req.urlObj.queryTokens.code, config.login.slack.redirect_uri, (id) => {
                    if (id) {
                        accountManager.fromSlackIdAuth(id, (account) => {
                            if (account) {
                                cb(account);
                            } else if (config.allowNewAccounts) {
                                var account = accountManager.createAccount();
                                account.authSlackUserEmailAndTeam = id;
                                accountManager.save(account, () => {
                                    cb(account);
                                    accountConfigManager.save(accountConfigManager.newConfigFor(account), () => {});
                                });
                            } else {
                                cb(false);
                            }
                        });
                    } else {
                        cb(null);
                    }
                });
            } else {
                cb(null);
            }
        break;

        case "google":
            if (req.urlObj.queryTokens.code) {
                GoogleOAuth.getUserId(req.urlObj.queryTokens.code, (id) => {
                    if (id) {
                        accountManager.fromGoogleIdAuth(id, (account) => {
                            if (account) {
                                cb(account);
                            } else if (config.allowNewAccounts) {
                                var account = accountManager.createAccount();
                                account.authGoogleUserId = id;
                                accountManager.save(account, () => {
                                    cb(account);
                                    accountConfigManager.save(accountConfigManager.newConfigFor(account), () => {});
                                });
                            } else {
                                cb(false);
                            }
                        });
                    } else {
                        cb(null);
                    }
                });
            } else {
                cb(null);
            }
        break;

        case "facebook":
            if (req.urlObj.queryTokens.code) {
                FacebookOAuth.getUserId(req.urlObj.queryTokens.code[0], (id) => {
                    if (id) {
                        accountManager.fromFacebookIdAuth(id, (account) => {
                            if (account) {
                                cb(account);
                            } else if (config.allowNewAccounts) {
                                var account = accountManager.createAccount();
                                account.authFacebookUserId = id;
                                accountManager.save(account, () => {
                                    cb(account);
                                    accountConfigManager.save(accountConfigManager.newConfigFor(account), () => {});
                                });
                            } else {
                                cb(false);
                            }
                        });
                    } else {
                        cb(null);
                    }
                });
            } else {
                cb(null);
            }
        break;

        case "android":
            if (req.urlObj.queryTokens.phoneAccess) {
                var self = this;
                accountManager.fromPhoneAccess(req.urlObj.queryTokens.phoneAccess, (acc) => {
                    if (acc) {
                        req.account = acc;
                        req.session = sessionManager.lazyForRequest(req);
                        req.session.setAccountId(req.reqT, acc.id);
                        res.writeHeader("302", {
                            Location: config.rootUrl,
                            "Set-Cookie": "sessID="+req.session.sessId +'; Path=/'
                        });
                        sessionManager.saveSession(req.session);
                    } else {
                        res.writeHeader("302", {
                            Location: "/login"
                        });
                    }
                    res.end();
                });
            } else {
                res.writeHeader("302", {
                    Location: "/login"
                });
                res.end();
            }
        break;

        default:
            cb(null);
        break;
    }
}

function makeLoginPage() {
    const
    slackUri = config.login.slack ? (config.login.slack.requestLoginUri
        +"?client_id=" +config.login.slack.clientId
        +"&scope=" +slackManager.getAuthScope().join(',')
        +"&redirect_uri=" +config.login.slack.redirect_uri) : "",
    googleUri = config.login.google ? (config.login.google.requestLoginUri
        +"?client_id=" +config.login.google.clientId
        +"&scope=" +(["openid", "email", "profile"]).join("%20")
        +"&redirect_uri=" +config.login.google.redirect_uri
        +"&response_type=code") : "",
    facebookUri = config.login.facebook ? (config.login.facebook.requestLoginUri
        +"?client_id=" +config.login.facebook.clientId
        +"&redirect_uri=" +config.login.facebook.redirect_uri) : null;

    return templates.header("Mimou - login", ["style.css"])
        +`<div class="login-services"><h1>Login</h1>`
        +(googleUri ? `<a href="${googleUri}"><img src="${config.rootUrl}btn_gogl_connect.png"></a>` : "")
        +(facebookUri ? `<a href="${facebookUri}"><img src="${config.rootUrl}btn_fcbk_connect.png"></a>` : "")
        +(slackUri ? `<a href="${slackUri}"><img src="${config.rootUrl}btn_slack_connect.png"></a>` : "")
        +`</div>`
        +templates.footer();
}

module.exports.match = function(url) {
    if (url.urlParts.length === 1) {
        return true;
    } else if (url.urlParts.length === 2 && (Object.keys(config.login).indexOf(url.urlParts[1]) >= 0 || url.urlParts[1] === "android")) {
        return true;
    }
    return false;
};

module.exports.exec = function(req, res, srv) {
    if (!req.urlObj.urlParts[1]) {
        if (req.urlObj.queryTokens["native"]) {
            req.session = sessionManager.lazyForRequest(req);
            req.session.isNative = true;
            sessionManager.saveSession(req.session);
            res.writeHeader("200", {
                "Set-Cookie": "sessID="+req.session.sessId +'; Path=/'
            });
        }
        res.end(makeLoginPage());
    } else {
        checkTokens(req.urlObj.urlParts[1], req, res, (account) => {
            if (account) {
                req.account = account;
                req.session = sessionManager.lazyForRequest(req);
                req.session.setAccountId(req.reqT, account.id);
                if (req.session.isNative) {
                    req.session.isNative = false;
                    res.writeHeader("302", {
                        Location: "intent:#Intent;scheme=mimou://open?token=" +account.generatePermanentPhoneAccess() +"&;package=com.knacki.mimou;end",
                        "Set-Cookie": "sessID="+req.session.sessId +'; Path=/'
                    });
                    accountManager.save(account);
                } else {
                    res.writeHeader("302", {
                        Location: config.rootUrl,
                        "Set-Cookie": "sessID="+req.session.sessId +'; Path=/'
                    });
                }
                sessionManager.saveSession(req.session);
                res.end();
            } else if (account === null) {
                res.end(makeLoginPage());
            } else {
                srv.execTemplate(require("./_403.js"), req, res);
            }
        });
    }
};

module.exports.needLogin = false;

