const system = require("../../../system");
const ServiceBase = require("../../sve.base");
const settings = require("../../../../config/settings");
const appconfig = system.getSysConfig();
const fs = require("fs")
class AppService extends ServiceBase {
  constructor() {
    super("common", ServiceBase.getDaoName(AppService));
    this.userS = system.getObject("service.auth.userSve");
    this.routeDao = system.getObject("db.common.routeDao");
    this.ossC = system.getObject("util.ossClient");
  }
  async getApp(p) {
    let app = this.cacheManager["AppCache"].cache(p.appkey, null);
    return app;
  }

  // 组装 前端 路由 
  async makeRoute(cds, parent) {
    let results = [];
    for (let item of cds) {
      let tmpResult = {};
      tmpResult.name = item.code;
      tmpResult.path = `/${item.code}`;
      tmpResult.component = "replace yours"
      tmpResult.meta = {
        hideInMenu: false,
        title: item.title,
        notCache: false,
        icon: 'replace yours'
      }
      if (item.children && item.children.length > 0) {
        tmpResult.children = [];
        tmpResult.children = await this.makeRoute(item.children, item);
      }
      results.push(tmpResult);
    }
    return results
  }
  async buildFrontRouter(funcJSON, appid) {
    var self = this;
    return this.db.transaction(async function (t) {
      let results = await self.makeRoute(funcJSON[0].children, null);
      let keyfile = self.getUUID() + ".json"
      let dirfile = "/tmp/" + keyfile
      fs.writeFileSync(dirfile, JSON.stringify(results));
      let result = await self.ossC.upfile(keyfile, dirfile);
      let upurl = result.url
      let upobj = { id: appid, docUrl: upurl }
      fs.unlinkSync(dirfile)
      await self.db.models.app.update(upobj, { where: { id: appid }, transaction: t })
      return { uprul: upurl }
    })
  }
  async findAllApps(uid) {
    var apps = null;
    var dicRtn = {};
    var wheresql = {};
    if (uid) {
      wheresql[this.db.Op.and] = {
        [this.db.Op.or]:
          [
            { isPublish: false, creator_id: uid },
            { isEnabled: true, isPublish: true }
          ],
      };
      apps = await this.dao.model.findAll({
        where: wheresql,
        attributes: ['id', 'name', 'appkey', 'showimgUrl', 'appType', 'docUrl', 'homePage']
      });
    } else {
      wheresql = { isEnabled: true, isPublish: true };
      apps = await this.dao.model.findAll({
        where: wheresql,
        attributes: ['id', 'name', 'appkey', 'showimgUrl', 'appType', 'docUrl', 'homePage']
      });
    }
    for (var app of apps) {
      var tmk = uiconfig.config.pdict.app_type[app.appType];
      if (!dicRtn[tmk]) {
        dicRtn[tmk] = [];
        dicRtn[tmk].push(app);
      } else {
        dicRtn[tmk].push(app);
      }
    }
    return dicRtn;
  }

  //创建应用
  //每个应用建立两个路由，一个api路由
  //对api路由启用jwt插件
  async create(pobj, qobj, req) {
    var self = this;
    return this.db.transaction(async function (t) {
      var app = await self.dao.create(pobj, t);
      //创建后台应用服务
      let urltmp = "http://" + app.backend
      if (app.backport) {
        urltmp += ":" + app.backport
      }
      //先检查后端服务是否存在，如果存在
      let svobj = await self.cjsonregister(AppService.newServiceUrl(), { name: app.name, url: urltmp })
      //添加路由,下面的绕过jwt检查
      let ps = ["/web/auth/userCtl/pmgetUserByCode", "/web/auth/userCtl/pmlogin", "/web/auth/userCtl/pmregister", "/web/auth/userCtl/pmSendVCode", "/web/auth/userCtl/pmloginByVCode"]
      let routeobj = await self.cjsonregister(AppService.newRouteUrl(app.name),
        { name: app.name, paths: ps, hosts: [app.domainName], strip_path: false })
        //如下要经过jwt检查
      let ps2 = ["/api", "/web"]
      let routeapi = await self.cjsonregister(AppService.newRouteUrl(app.name), { name: app.name + "_api", hosts: [app.domainName], paths: ps2, strip_path: false })
      let r1 = await self.routeDao.create({ name: app.name, center_id: routeobj.id, app_id: app.id, shosts: app.domainName, spaths: ps.join(",") }, t);
      let r2 = await self.routeDao.create({ name: app.name + "_api", center_id: routeapi.id, app_id: app.id, shosts: app.domainName, spaths: ps2.join(",") }, t);
      //给api路由启动插件
      await self.cjsonregister(AppService.bindPluginUrl(app.name + "_api"), { name: "jwt" })
      if (svobj && routeobj && r1 && r2) {
        try {
          app.appkey = svobj.id;
          await app.save({ transaction: t });
        } catch (e) {
          await self.cdel(AppService.routeUrl(app.name))
          await self.cdel(AppService.routeUrl(app.name + "_api"))
          await self.cdel(AppService.serviceUrl(app.name))
        }
      } else {
        throw new Error("创建应用服务失败");
      }
      return app;
    });
  }
  async translateInitSels(funcobjs) {
    funcobjs.forEach((item) => {
      console.log(item.title)
      if (item.children && item.children.length > 0) {
        this.translateInitSels(item.children)
      } else {
        if (item.auths && item.auths.length > 0) {
          item.sels = []
        }
      }
    })
  }
  async saveFuncTree(pobj) {
    var self = this;
    return this.db.transaction(async function (t) {
      //如果存在functionJSON,那么就需要转换，构建编码路径
      if (pobj.funcJson) {
        // let funcobjs = JSON.parse(pobj.functionJSON)
        await self.translateInitSels(pobj.funcJson)
        pobj.functionJSON = JSON.stringify(pobj.funcJson)
      }
      let appcache = await self.cacheManager["AppCache"].cache(pobj.appkey);
      let upobj = { id: appcache.id, functionJSON: pobj.functionJSON }
      await self.dao.update(upobj, t)
      //令缓存失效
      await self.cacheManager["AppCache"].invalidate(pobj.appkey);
      let appcache2 = await self.dao.model.findById(appcache.id, { transaction: t });
      return { funcJson: JSON.parse(appcache2.functionJSON) }
    })
  }
  //应用
  async update(pobj, qobj) {
    var self = this;
    return this.db.transaction(async function (t) {
      //如果存在functionJSON,那么就需要转换，构建编码路径
      if (pobj.functionJSON != "") {
        let funcobjs = JSON.parse(pobj.functionJSON)
        //await self.translateWithBizCode(funcobjs,null)
        pobj.functionJSON = JSON.stringify(funcobjs)
      }
      await self.dao.update(pobj, t)
      let upobj = await self.dao.findById(pobj.id)
      //令缓存失效
      await self.cacheManager["AppCache"].invalidate(upobj.appkey);
      return upobj
    })
  }

  //删除应用
  async delete(pobj, qobj) {
    var self = this;
    return this.db.transaction(async function (t) {
      let delobj = await self.dao.delete(pobj, t)
      //令缓存失效
      await self.cacheManager["AppCache"].invalidate(delobj.appkey);
      //删除路由
      await self.cdel(AppService.routeUrl(pobj.name));
      //删除api路由
      await self.cdel(AppService.routeUrl(pobj.name + "_api"));
      //删除服务
      await self.cdel(AppService.serviceUrl(pobj.name));
      return {}
    })
  }

  async findAndCountAll(obj) {
    var self = this;
    const apps = await super.findAndCountAll(obj);
    return apps;
  }
}
module.exports = AppService;
// (async ()=>{
//   let u=new AppService();
//  //  let x=await u.cregister("jiangong")
//  //  console.log(x)
//  // let x=await u.cunregister("jiangong")
//  //  console.log(x)
//   // let t=await u.cmakejwt()
//   // console.log(t)
//   //let ux=await u.cjsonregister(AppService.newRouteUrl("test-service2"),{name:"test-service2",hosts:["ttest1.com"]})
//   //let ux=await u.cjsonregister(AppService.newServiceUrl(),{name:"test-service3",url:"http://zhichan.gongsibao.com"})
//   //let ux=await u.cdel(AppService.routeUrl("test-service2"))
//   //let ux=await u.cdel(AppService.serviceUrl("test-service2"))
//   //  let ux=await u.create({name:"test4-service",backend:"zhichan-service",domainName:"domain.com"})
//   //   console.log(ux);
//   // let delrtn=await u.delete({id:2,name:"test4-service"})
//   // console.log(delrtn);
// })()