 //#import pigeon.js
//#import login.js
//#import Util.js
//#import app.js
//#import session.js
//#import file.js
//#import pigeon.js
//#import session.js
//#import $owl_backend_session:services/modelService.jsx
//#import $owl_mall_u:services/modelService.jsx
//#import $owl_orgs:services/modelService.jsx
//#import $owl_org_modules:services/modelService.jsx
//#import $owl_roles:services/modelService.jsx
//#import $owl_permission:services/modelService.jsx
//#import $owlPermission:services/RolesService.jsx


function getPermissions(roleId) {
    var searchArgs = {
        roleId: roleId
    }
    var sr = owl_permissionService.search(null, searchArgs, null, 0, 10000, null);
    if (sr.state === 'ok') {
        return sr.list;
    }
    return [];
}

function getAllowedTables(permissions) {
    var tableIds = [];
    permissions.map(function (p) {
        if ((p.permission_same_org && (p.permission_same_org.list === 'allowed' || p.permission_same_org.listAll === 'allowed')) || (p.permission_sub_org && (p.permission_sub_org.list === 'allowed' || p.permission_sub_org.listAll === 'allowed' ))) {
           if(p.tables){
               p.tables.forEach(function(table){
                   if(tableIds.indexOf(table.tableId) == -1){
                       tableIds.push(table.tableId);
                   }
               });
           }
        }
    });
    return tableIds;
}

function getDeniedTables(permissions) {
    var tableIds = [];

    permissions.map(function (p) {
        if ((p.permission_same_org && p.permission_same_org.list === 'denied') && (p.permission_sub_org && p.permission_sub_org.list === 'denied')) {
            if(p.tables){
                p.tables.forEach(function(table){
                    if(tableIds.indexOf(table.tableId) == -1){
                        tableIds.push(table.tableId);
                    }
                });
            }
        }
    });
    return tableIds;
}

function filterRoleApps(allApps, roles, roleId) {

    var role = null;
    if (!roles) {
        return allApps;
    }

    for (var i = 0; i < roles.length; i++) {
        var r = roles[i];
        if (r.id === roleId) {
            role = r;
        }
    }

    if (!role) {
        return allApps;
    }
    if (role.id === '0') {
        return allApps;
    }


    var permissions = getPermissions(roleId);

    var allow_arr = [];
    var deny_arr = [];

    allow_arr = getAllowedTables(permissions);
    deny_arr = getDeniedTables(permissions);


    var retApps = [];

    var isAllAllowed = (allow_arr.indexOf('all') > -1);
    // $.log("isAllAllowed=" + isAllAllowed+ "allow_arr=" + JSON.stringify(allow_arr)+",allow_tables=" + allow_tables);
    allApps.forEach(function (app) {
        if (deny_arr.indexOf(app.id) > -1) {
            return;
        }
        if (isAllAllowed) {
            retApps.push(app);
        } else if (allow_arr.indexOf(app.id) > -1) {
            retApps.push(app);
        }
    });
    return retApps;
}

function filterOrgsApps(apps,orgId) {
    // if(!orgId){
    //     return apps;
    // }
    var isid = SessionService.getSessionId(request);
    var sessionId = 'owl_backend_session_' + isid;

    var session = owl_backend_sessionService.get(sessionId);
    var userId = session.userId;

    if (orgId === '0') {
        return apps;
    }
    var org = owl_orgsService.get(orgId);

    var org_modules = org.org_modules;
    if (!org_modules) {
        return [];
    }
    var privilegeApps = {};
    for (var i = 0; i < org_modules.length; i++) {
        var om = org_modules[i];
        var org_module = owl_org_modulesService.get(om.id);
        // $.log("om.id=" + om.id + ", org_module=" + JSON.stringify(org_module));
        if (org_module && org_module.modules) {
            if (org_module.modules == '*') {
                return apps;
            }
            var arrAppId = org_module.modules.split(",");
            arrAppId.forEach(function (appId) {
                privilegeApps["owl_" + appId] = appId;
            });
        }
        if(org_module && org_module.tables){
            org_module.tables.forEach(function(table){
                privilegeApps[table.tableId] = table.tableId;
            });
        }
    }
    return apps.filter(function (app) {
        if (privilegeApps[app.id]) {
            return true;
        } else {
            return false;
        }
    });
}

(function () {

    var params = JSON.parse($body);
    var project = params.project;
    var merchantId = params.m;
    var roleId = params.rroleId;
    var orgId = params.rorgId;
    $.log("merchantId=" + merchantId + ",project=" + project);
    var allapps = AppService.getIndependentApps(merchantId, 0, -1);

    matchApps = allapps;

    matchApps = matchApps.filter(function (app) {
        try {
            var meta = AppService.getAppMeta(app.id);
        } catch (e) {
            $.log("meta is not valid:" + app.id);
            return false;
        }
        if (!meta) {
            $.log("isMeta==false,app.id=" + app.id);
            return false;
        }
        if (meta.isWidget == true) {
            $.log("isWidget==true,app.id=" + app.id);
            return false;
        }

        try {
            var subMeta = meta["#meta"];
            if (!subMeta) {
                $.log("#meta not exists:" + app.id);
                return false;
            }

            if (subMeta.hide === 'true') {
                return false;
            }
            // if (project && subMeta.project) {
            //     if (subMeta.project != project) {
            //         $.log("subMeta.project != project, subMeta.project=" + subMeta.project);
            //         return false;
            //     }
            // }
            if (subMeta.group) {
                if (typeof subMeta.group == 'string') {
                    app.group = {
                        name: subMeta.group,
                        id: subMeta.group
                    }
                } else {
                    app.group = subMeta.group;
                }

            }
            if (subMeta.pos) {
                app.pos = subMeta.pos;
            }
            app.name = subMeta.rem;
        } catch (e) {
            // $.log("#meta error:" + app.id);
            return false;
        }
        app.name = subMeta.rem;
        // $.log("success:app.name=" + app.name);
        return true;
    });

    var orgApps = filterOrgsApps(matchApps,orgId);

    var isid = SessionService.getSessionId(request);
    var sessionId = 'owl_backend_session_' + isid;

    var params = JSON.parse($body);

    var session = owl_backend_sessionService.get(sessionId);

    var userId = session.userId;

    var roles = getRoles(orgId,userId);


    var roleApps = filterRoleApps(orgApps, roles, roleId);
    var apps = {};
    roleApps.forEach(function (app) {
        if (app.group) {
            var appGroupId = app.group.id;
            if(appGroupId == 'basicInfo'){
                // appGroupId = 'basic';
                $.log("appGroupId=" + appGroupId + ",app.id=" + app.id + ",app.name=" + app.name);
            }


            var group = apps[appGroupId];
            if (!group) {
                group = {
                    name: app.group.name,
                    groupId: appGroupId,
                    icon: app.group.icon || "folder",
                    pos: app.group.pos,
                    children: []
                }
            }
            if (app.group.level2) {
                var id = app.group.level2.id;

                //find level2
                var level2 = findLevel2(group.children, id);
                if (!level2) {
                    level2 = {
                        name: app.group.level2.name,
                        id: id,
                        icon: app.group.level2.icon || "folder",
                        pos: app.group.level2.pos,
                        children: []
                    }
                    group.children.push(level2);
                }
                level2.children.push({
                    path: "/owl/" + app.id,
                    id:app.id,
                    name: app.name,
                    icon: app.icon,
                    pos: app.pos
                })
            } else {
                group.children.push({
                    path: "/owl/" + app.id,
                    id:app.id,
                    name: app.name,
                    icon: app.icon,
                    pos:app.pos
                });
            }
            apps[appGroupId] = group;
        } else {
            apps[app.id] = {
                path: "/owl/" + app.id,
                id:app.id,
                name: app.name,
                icon: app.icon,
                pos:app.pos
            };
        }
    });

    var keys = Object.keys(apps);
    var menuItems = [];
    for (var i = 0; i < keys.length; i++) {
        var item = apps[keys[i]];
        menuItems.push(item);
        if (item.children) {
            item.children.sort(function (a, b) {
                if (typeof a.pos == 'undefined') {
                    a.pos = 100;
                }
                if (typeof b.pos == 'undefined') {
                    b.pos = 100;
                }
                return a.pos - b.pos
            });
            item.children.forEach(function(level2){
                if(level2.children){
                    level2.children.sort(function (a, b) {
                        if (typeof a.pos == 'undefined') {
                            a.pos = 100;
                        }
                        if (typeof b.pos == 'undefined') {
                            b.pos = 100;
                        }
                        return a.pos - b.pos
                    });
                }
            });
        }
    }

    menuItems.sort(function (a, b) {
        return a.pos - b.pos;
    });


    var ret = {
        state: "ok",
        menu: menuItems,
        // apps:apps,
        // orgApps:orgApps,
        // roleApps:roleApps,
        roles: roles,
        roleId: roleId,
        userId: userId,
        orgId: orgId,
        // allApps:allapps||['空']
    }
    out.print(JSON.stringify(ret));
})();

function findLevel2(children, id) {
    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (child.id == id) {
            return child;
        }
    }
    return null;
}