text: "use strict"; require("dotenv").config();
  
  
  
  //  P A C K A G E S
  
  const async = require("async");
  const bodyParser = require("body-parser");
  const cors = require("cors");
  const CronJob = require("cron").CronJob;
  const express = require("express");
  const fs = require("graceful-fs");
  const octokit = require("@octokit/rest")();
  const redis = require("redis");
  const request = require("request");
  const serveStatic = require("serve-static");
  const sslRedirect = require("heroku-ssl-redirect");
  
  
  
  //  V A R I A B L E S
  
  const app = express();
  const jsonParser = bodyParser.json();
  const port = process.env.PORT || 8080;
  const redisClient = redis.createClient(process.env.REDISCLOUD_URL);
  const textParser = bodyParser.text({ limit: "256kb" });
  
  let Slack;
  let slack;
  
  if (typeof process.env.GITHUB_OAUTH_TOKEN !== "undefined") {
    octokit.authenticate({
      type: "oauth",
      token: process.env.GITHUB_OAUTH_TOKEN
    });
  }
  
  if (typeof process.env.SLACK_WEBHOOK_URL !== "undefined") {
    Slack = require("slack-node");
    slack = new Slack();
    slack.setWebhook(process.env.SLACK_WEBHOOK_URL);
  }
  
  
  
  //  P R O G R A M
  
  app.listen(port);
  app.use(sslRedirect());
  app.use(serveStatic(`${__dirname}/content/.vuepress/dist`));
  app.use(cors());
  
  
  
  app.get("/github-feed", (req, res) => {
    redisClient.zrevrange("events", 0, 9, (err, reply) => {
      const events = [];
  
      reply.forEach(item => events.push(JSON.parse(item)));
      res.json(events);
    });
  });
  
  app.get("/*", (req, res) => {
    if (fs.existsSync(`${__dirname}/content/.vuepress/dist${req.path}.html`)) {
      res.redirect(`${req.path}.html`);
    } else {
      res.status(404);
      res.send("Not found");
    }
  });
  
  
  
  app.post("/forward", jsonParser, (req, res) => {
    const allowedMethods = ["wallet_send", "resolve", "publish"];
  
    if (typeof req.body.method === "undefined") return;
  
    if (allowedMethods.includes(req.body.method)) {
      if (req.body.method === "wallet_send") {
        req.body.amount = 0.01; // Hardcode the wallet_send amount
  
        const allowedClaims = [ // Whitelist claim ids
          "fbdcd44a97810522d23d5f1335b8ca04be9d776c",
          "de7f7fa33e8d879b2bae7238d2bdf827a39f9301",
          "5b7c7a202201033d99e1be2930d290c127c0f4fe",
          "a1372cf5523885f5923237bfe522f02f5f054362"
        ];
  
        if (!allowedClaims.includes(req.body.claim_id)) res.json({});
      }
  
      if (req.body.method === "publish") {
        req.body.bid = 0.001; // Hardcode the publish amount
  
        // Fix the internal image path in daemon
        req.body.file_path = process.env.LBRY_DAEMON_IMAGES_PATH + req.body.file_path;
      }
  
      req.body.access_token = process.env.LBRY_DAEMON_ACCESS_TOKEN;
  
      request({
        url: "http://daemon.lbry.tech",
        qs: req.body
      }, (error, response, body) => {
        body = JSON.parse(body);
        if (typeof body.error !== "undefined") logSlackError("ERROR: Got error from daemon:\n", "```" + JSON.stringify(body.error) + "```");
        res.json(body);
      });
    }
  });
  
  app.post("/upload-image", textParser, (req, res) => {
    request({
      method: "PUT",
      url: "http://daemon.lbry.tech/images.php",
      headers: {
        "Content-Type": "text/plain"
      },
      qs: {
        access_token: process.env.LBRY_DAEMON_ACCESS_TOKEN
      },
      body: req.body,
    }, (error, response, body) => {
      body = JSON.parse(body);
      res.json(body);
    });
  });
  
  
  
  //  H E L P E R S
  
  logSlackError(`Server started at port \`${port}\``);
  
  function updateGithubFeed() {
    octokit.activity.getEventsForOrg({
      org: "lbryio",
      per_page: 20,
      page: 1
    }).then(({ data }) => {
      async.eachSeries(data, (item, callback) => {
        const eventString = JSON.stringify(item);
  
        redisClient.zrank("events", eventString, (err, reply) => {
          if (reply === null) redisClient.zadd("events", item.id, eventString, callback);
          else callback();
        });
      }, () => {
        // Keep the latest 50 events
        redisClient.zremrangebyrank("events", 0, -51);
      });
    }).catch(err => {
      logSlackError("ERROR: Unable to update Github feed:\n", "```" + JSON.stringify(err) + "```");
    });
  }
  
  function logSlackError(text) {
    if (typeof slack === "undefined") return;
  
    slack.webhook({
      channel: "dottech-errors",
      username: "lbrytech-bot",
      text: text
    }, (err, response) => { // eslint-disable-line
      // do nothing?
    });
  }
  
  // Update Github feed every minute
  new CronJob("0 * * * * *", updateGithubFeed, null, true, "America/Los_Angeles");
  
  
  
  //  E X P O R T
  
  module.exports = exports = app;
  