import sql from "../sql.mjs";
import lib from "../lib.mjs";
import { exec } from "child_process";
import search from "./inc/search.mjs";

const auth = async (req, res, next) => {
  if(!req.session) {
    return res.reply({
      code: 401,
      body: "401 - Unauthorized"
    });
  }
  return next();
};

export default (router, tpl) => {

  router.get(/^\/login(\/)?$/, async (req, res) => {
    if(req.cookies.session)
      return res.reply({ body: "du bist schon eingeloggt lol" });
    res.reply({
      body: tpl.render("login", { theme: req.cookies.theme ?? "f0ck" })
    });
  });
  
  router.post(/^\/login(\/)?$/, async (req, res) => {
    const user = await sql("user").where("login", req.post.username.toLowerCase()).limit(1);
    if(user.length === 0)
      return res.reply({ body: "user doesn't exist or wrong password" });
    if(!(await lib.verify(req.post.password, user[0].password)))
      return res.reply({ body: "user doesn't exist or wrong password" });
    const stamp = ~~(Date.now() / 1e3);

    await sql("user_sessions") // delete unused sessions
      .where('last_action', '<=', (Date.now() - 6048e5))
      .andWhere('kmsi', 0)
      .del();
  
    const session = lib.md5(lib.createID());
    await sql("user_sessions").insert({
      user_id: user[0].id,
      session: lib.md5(session),
      browser: req.headers["user-agent"],
      created_at: stamp,
      last_used: stamp,
      last_action: "/login",
      kmsi: typeof req.post.kmsi !== 'undefined' ? 1 : 0
    });

    return res.writeHead(301, {
      "Cache-Control": "no-cache, public",
      "Set-Cookie": `session=${session}; Path=/; Expires=Fri, 31 Dec 9999 23:59:59 GMT`,
      "Location": "/"
    }).end();
  });
  
  router.get(/^\/logout$/, auth, async (req, res) => {
    const usersession = await sql("user_sessions").where("id", req.session.sess_id);
    if(usersession.length === 0)
      return res.reply({ body: "nope 2" });
    
    await sql("user_sessions").where("id", req.session.sess_id).del();
    return res.writeHead(301, {
      "Cache-Control": "no-cache, public",
      "Set-Cookie": "session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT",
      "Location": "/"
    }).end();
  });
  
  router.get(/^\/login\/pwdgen$/, async (req, res) => {
    res.reply({
      body: "<form action=\"/login/pwdgen\" method=\"post\"><input type=\"text\" name=\"pwd\" placeholder=\"pwd\" /><input type=\"submit\" value=\"f0ck it\" /></form>"
    });
  });
  router.post(/^\/login\/pwdgen$/, async (req, res) => {
    res.reply({
      body: await lib.hash(req.post.pwd)
    });
  });

  router.get(/^\/admin(\/)?$/, auth, async (req, res) => { // frontpage

    res.reply({
      body: tpl.render("admin", { totals: await lib.countf0cks(), session: req.session }, req)
    });
  });
  
  router.get(/^\/admin\/sessions(\/)?$/, auth, async (req, res) => {
    const rows = await sql("user_sessions")
      .leftJoin("user", "user.id", "user_sessions.user_id")
      .select("user_sessions.*", "user.user")
      .orderBy("user_sessions.last_used", "desc");
  
    res.reply({
      body: tpl.render("admin/sessions", {
        session: req.session,
        sessions: rows,
        totals: await lib.countf0cks()
      }, req)
    });
  });
  
  router.get(/^\/admin\/test(\/)?$/, auth, async (req, res) => {
    let ret;
    if(Object.keys(req.url.qs).length > 0) {
      let tag = req.url.qs.tag;
      let rows;

      if(tag.startsWith('src:')) {
        tag = tag.substring(4);
        ret = await sql('items')
          .where('src', 'ilike', '%'+tag+'%')
          .limit(500);
      }
      else {
        rows = await sql("tags")
          .select("items.id", "items.username", "tags.tag")
          .leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
          .leftJoin("items", "items.id", "tags_assign.item_id")
          .where("tags.tag", "like", '%'+tag+'%')
          .limit(500);
        ret = search(rows, tag);
      }
    }
  
    res.reply({
      body: tpl.render("admin/search", {
        result: ret,
        totals: await lib.countf0cks(),
        session: req.session
      }, req)
    });
  });

  router.get(/^\/admin\/log(\/)?$/, auth, async (req, res) => {
    exec("journalctl -qeu f0ck --no-pager", (err, stdout) => {
      res.reply({
        body: tpl.render("admin/log", {
          log: stdout.split("\n").slice(0, -1)
        }, req)
      });
    });
  });

  return router;
};
