const System = require("../system");
const redis = require("redis");
const settings = require("../../config/settings");
const bluebird = require("bluebird");
bluebird.promisifyAll(redis);
// const logCtl=System.getObject("web.oplogCtl");
class RedisClient {
  constructor() {
    const redisConfig = settings.redis();
    this.client = redis.createClient({
      host: redisConfig.host,
      port: redisConfig.port,
      password: redisConfig.password,
      db: redisConfig.db,
      retry_strategy: function (options) {
        // if (options.error && options.error.code === 'ECONNREFUSED') {
        //     // End reconnecting on a specific error and flush all commands with
        //     // a individual error
        //     return new Error('The server refused the connection');
        // }
        console.log("redis connecting.....try")
        if (options.total_retry_time > 1000 * 60 * 60) {
          // End reconnecting after a specific timeout and flush all commands
          // with a individual error
          return new Error('Retry time exhausted');
        }
        if (options.attempt > 10) {
          // End reconnecting with built in error
          return 10000;
        }
        // reconnect after
        return Math.min(options.attempt * 100, 3000);
      }
    });
    this.client.on("error", function (err) {
      console.log("Error " + err);
    });
    this.subclient = this.client.duplicate();
    this.subclient.on("error", function (err) {
      console.log("Error " + err);
    });
    var self = this;

  }
  async subscribe (channel) {
    return this.subclient.subscribeAsync(channel);
  }
  async unsubscribe (channel) {
    //this.chatserver=null;
    return this.subclient.unsubscribeAsync(channel);
  }
  async publish (channel, msg) {
    console.log("publish--" + channel + ":" + msg);
    return this.client.publishAsync(channel, msg);
  }
  async notifyConsume (channel, consumetarget, val) {
    await this.client.rpush(consumetarget, val);
    console.log("publish--" + channel + ":" + consumetarget);
    return this.client.publishAsync(channel, consumetarget);
  }
  async rpush (key, val) {
    return this.client.rpushAsync(key, val);
  }
  async llen (key) {
    return this.client.llenAsync(key);
  }
  async rpushWithEx (key, val, t) {
    var p = this.rpush(key, val);
    this.client.expire(key, t);
    return p;
  }
  async rpop (key) {
    return this.client.rpopAsync(key);
  }
  async lpop (key) {
    return this.client.lpopAsync(key);
  }
  async lrem (key, val) {
    return this.client.lremAsync(key, 1, val);
  }
  async ltrim (key, s, e) {
    return this.client.ltrimAsync(key, s, e);
  }
  async clearlist (key) {
    await this.client.ltrim(key, -1, -1);
    await this.client.ltrim(key, 1, -1);
    return 0;
  }
  async flushall () {
    console.log("sss");
    return this.client.flushallAsync();
  }
  async keys (p) {
    return this.client.keysAsync(p);
  }
  async set (key, val) {
    if (typeof val == "undefined" || typeof key == "undefined") {
      console.log("......................cache val undefined");
      console.log(key);
      return null;
    }
    return this.client.setAsync(key, val);
  }
  async setWithEx (key, val, t) {
    var p = this.client.setAsync(key, val);
    this.client.expire(key, t);
    return p;
  }
  async get (key) {

    return this.client.getAsync(key);
  }
  async delete (key) {
    return this.client.delAsync(key);
  }
  async hdel (key, field) {
    return this.client.hdelAsync(key, field);
  }
  async hmset (key, jsonObj) {
    return this.client.hmsetAsync(key, jsonObj);
  }
  async hmsetWithEx (key, jsonObj, t) {
    var p = this.client.hmsetAsync(key, jsonObj);
    this.client.expire(key, t);
    return p;
  }
  async hgetall (key) {
    return this.client.hgetallAsync(key);
  }
  async hincrby (key, f, n) {
    return this.client.hincrbyAsync(key, f, n);
  }

  async sadd (key, vals) {
    await this.client.saddAsync(key, ...vals);
    return this.scard(key);
  }
  async scard (key) {
    return this.client.scardAsync(key);
  }
  async srem (key, val) {
    return this.client.sremAsync(key, val);
  }
  async sismember (key, val) {
    return this.client.sismemberAsync(key, val);
  }
  async smembers (key) {
    return this.client.smembersAsync(key);
  }
  async exists (key) {
    return this.client.existsAsync(key);
  }
  async incr (key) {
    return this.client.incrAsync(key);
  }
  async close () {
    this.client.quit();
  }
}
module.exports = RedisClient;

// (async () => {
//   function isFail (taskName, lastAccess) {
//     let n = Date.now()
//     let postMinute = (n - lastAccess) / 1000 / 60
//     let tnameparams = taskName.split("|")
//     let tname = tnameparams[0].trim()
//     let mtype = tnameparams[1].trim()
//     let pvalue = Number(tnameparams[2].trim())
//     if (mtype == "i") {//每几分钟执行一次
//       console.log(taskName, postMinute, "xxxxxxxxxxxxxxxxxxxxxxx")
//       //如果流失的时间大于循环调度时间,则报异常到丁丁
//       if (postMinute > pvalue) {
//         this.sendDing(tname + "可能失联啦...请检查")
//       }
//     }
//     if (mtype == "a") {//
//       let onedaym = 24 * 60
//       if (postMinute > onedaym) {
//         this.sendDing(tname + "可能失联啦...请检查")
//       }
//     }
//   }
//   var client = new RedisClient();
//   client.hmset("tasks", { "task1|i|1000": 1599793212470, "task2|i|1000": 1599793212476 }).then(function (r) {
//     console.log(r);
//   });
//   let x = await client.hgetall("tasks")

//   for (let entry in x) {
//     isFail(entry, x[entry])
//   }
// })()

// client.keys('*').then(s => {
//   console.log(s);
// });
// let clients = {};
// clients.watcher = redis.createClient({ ... });
// clients.alterer = clients.watcher.duplicate();
// client.sadd("h", ["ok", "jy", "ok"]).then(function (r) {
//   console.log(r);
// });
// client.smembers("h").then(function (r) {
//   console.log(r);
// });
// client.sismember("h", "ok").then(function (r) {
//   console.log(r);
// });
// console.dir(client); ti.exec(callback)回调函数参数err：返回null或者Array，出错则返回对应命令序列链中发生错误的错误信息，这个数组中最后一个元素是源自exec本身的一个EXECABORT类型的错误
// r.set("hello", "oooo").then(function (result) {
//   console.log(result);
// });
// r.get("hello").then(function (result) {
//   console.log(result);
// });
// client.hmset("user_1", { name: "jy", age: 13 }).then(function (r) {
//   console.log(r);

// });
// client.hincrby("user_1", "age", 2).then(function (r) {
//   console.log(r);
//   setTimeout(function () {
//     client.hgetall("user_1").then(function (u) {
//       console.log(u);
//     });
//   }, 3000);
// });
