module NaiveRBAC{
  function initDAC(req){
    Global.acceptList = {
    };
    Global.applyList = {
    };
    Global.roles = [];
    Global.roleToPer = {
    };
    var obj = JSON.parse(Global.Resources.loadAsString("/naiveRBAC/role.json"));
    for (var key in obj){
      Global.roles.push(key);
      Global.roleToPer[key] = obj[key];
    }
    Global.owner = req;
  }
  function checkPermission(req){
    var caller = YancloudUtil.getCaller(1);
    var name = caller.name;
    return checkInternal(name,req);
  }
  function checkInternal(name,pubKey){
    if (pubKey==Global.owner) return true;
    var roleList = Global.acceptList[pubKey];
    if (roleList!=undefined){
      for (var i=0;i<roleList.length;i++){
        if (Global.roleToPer[roleList[i]].indexOf(name)!=-1){
          return true;
        }
      }
    }
    return false;
  }
  export function hasPermission(arg){
    return checkInternal(arg,requester);
  }
  export function hasNewRequest(arg){
  }
  export function accept(req){
    if (!checkPermission(requester)){
      return "access denied";
    }
    req = JSON.parse(req);
    var pubKey = req.pubKey;
    var roles = req.roles;
    if (Global.acceptList[pubKey] == undefined){
      Global.acceptList[pubKey] = [];
    }
    for (var i=0; i<roles.length;i++){
      if (Global.roles.indexOf(roles[i])!=-1){
        if (Global.acceptList[pubKey].indexOf(roles[i])==-1){
          Global.acceptList[pubKey].push(roles[i]);
        }
      }
    }
    var newList = [];
    if (Global.applyList[pubKey]==undefined){
      Global.applyList[pubKey] = [];
    }
    for (var i=0;i<Global.applyList[pubKey].length;i++){
      if (roles.indexOf(Global.applyList[pubKey][i])==-1){
        newList.push(Global.applyList[pubKey][i]);
      }
    }
    Global.applyList = newList;
    return true;
  }
  export function cancel(req){
    if (!checkPermission(requester)){
      return "access denied";
    }
    req = JSON.parse(req);
    var pubKey = req.pubKey;
    var roles = req.roles;
    var newList = [];
    var removedList = [];
    var oldList = Global.acceptList[pubKey];
    for (var i=0;i<oldList.length;i++) {
      if (roles.indexOf(oldList[i])!=-1){
        removedList.push(oldList[i]);
      } else {
        newList.push(oldList[i]);
      }
    }

    Global.acceptList[pubKey] = newList;
    if (Global.applyList[pubKey]==undefined){
      Global.applyList = [];
    }
    for (var i=0;i<newList.length;i++){
      if (Global.acceptList[pubKey].indexOf(newList[i])==-1){
        Global.acceptList[pubKey].push(newList[i]);
      }
    }
    return true;
  }
  export function apply(remark){
    if (remark != undefined && requester !=undefined){
      remark = JSON.parse(remark);
      if (Global.applyList[requester]==undefined){
        Global.applyList[requester] = [];
      }
      for (var i=0;i<remark.length;i++){
        if (Global.roles.indexOf(remark[i])==-1){
          continue;
        }
        if (Global.applyList[requester].indexOf(remark[i])!=-1){
          Global.applyList[requester].push(remark[i]);
        }
      }
      return "success";
    }
    return "failed"
  }
  export function deleteRole(arg){
    if (!checkPermission(requester)){
      return "access denied";
    }
    var newList = [];
    var index = Global.roles.indexOf(arg);
    if (index!=-1){
      Global.roles.splice(index, 1);
    }
    if (Global.roleToPer[arg]!=undefined){
      Global.roleToPer[arg]=undefined;
    }
    return "success";
  }

  @Description("Sample Arg: {\"role\":\"customer\",\"permissions\":[\"fun1\",\"fun2\"]}")
  export function addRole(arg){
    if (!checkPermission(requester)){
      return "access denied";
    }
    arg =  JSON.parse(arg);
    arg.role;
    arg.permissions;
    if (arg.role!=undefined && arg.permissions!=undefined)
       Global.roleToPer[arg.role] = arg.permissions;
    return "success";
  }
  export function needRender(arg){
    return true;
  }
  export function getACFrame(arg){
    return "/naiveRBAC/naiveRBAC.html";
  }
  export function getMainFrame(arg){
    return "/naiveRBAC/naiveRBAC.html";
  }
  export function loadResource(arg){
    return Global.Resources.loadAsString(arg);
  }
  export function isOwner(arg){
    return Global.owner==requester;
  }
  //TODO paging?
  export function getApplyList(arg){
    return JSON.stringify(Global.applyList);
  }
  //TODO paging?
  export function getAcceptList(arg){
    return JSON.stringify(Global.acceptList);
  }
}
