require("dotenv").config();

const express = require("express");
const app = express();
const http = require("http");

import { EventLocalInit } from "./EventLocalInit";
import { MessageLocalInit, Messager } from "./MessageLocalInit";
import { ApiLocalInit } from "./ApiLocalInit";
import { BrokerProxy } from "broker-proxy-rebbitmq";
import { HealthLib } from "./HealthLib";
import MySQLModule from "./MySQLModule"; 

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

var os = require("os");
var ifaces = os.networkInterfaces();
export default class EventLocal {
  private JWT;
  private static broker: BrokerProxy;
  private static message: Messager;
  public static localHost: string;
  constructor() {
    Object.keys(ifaces).forEach(function(ifname) {
      var alias = 0;
      ifaces[ifname].forEach(function(iface) {
        if ("IPv4" !== iface.family || iface.internal !== false) {
          return;
        }
        if (alias >= 1) {
          console.log(ifname + ":" + alias, iface.address);
        } else {
          EventLocal.localHost = iface.address;
        }
        ++alias;
      });
    });
  }
  async onInit() : Promise<EventLocal> {
    const mysql = new MySQLModule();
    await mysql.onInit();
    return new Promise(async (resolve, rej) => {
      let hl = new HealthLib(
        EventLocal.localHost,
        +process.env.SERVICE_PORT,
        +process.env.SERVICE_VERSION_API,
        process.env.SERVICE_NAME
      );

      app.set("port", process.env.SERVICE_PORT);
      app.use((req, res, next) => {
        res.header("Access-Control-Allow-Origin", "*");
        res.header(
          "Access-Control-Allow-Methods",
          "GET, POST, PUT, DELETE, OPTIONS"
        );
        res.header(
          "Access-Control-Allow-Headers",
          "Origin, X-Requested-With, Content-Type, Accept, access"
        );
        next();
      });
      app.use(express.json());

      app.get("/v1/health", (req, res) => {
        hl.health();
        res.send("0");
      });

      app.get("/help", (req, res) => {
        let html = "<h1>Помощь для разработчика</h1>";

        if (Array.isArray(global.EVENT_CHANNEL)) {
          html += "<h3>Подписка на события брокера</h3>";
          for (let f of global.EVENT_CHANNEL) {
            html += `<p><b>${f.event}</b> - ${f.callback}</p>`;
          }
        }
        if (Array.isArray(global.MESSAGE_CHANNEL)) {
          html += `<hr/><h3>События телеграмм команд</h3>`;
          for (let f of global.MESSAGE_CHANNEL) {
            html += `<p><b>${f.event.toString()}</b> - ${f.callback}</p>`;
          }
        }
        if (Array.isArray(global.API_CHANNEL)) {
          html += `<hr/><p>События WEB API</p>`;
          for (let f of global.API_CHANNEL) {
            html += `<p><b>[${f.method}] ${f.url} </b> -  ${f.callback}</p>`;
          }
        }
        res.send(html);
      });

      app.listen(app.get("port"), async () => {
        console.log(
          "[*] Сервис запущен локально: " +
            EventLocal.localHost +
            ":" +
            process.env.SERVICE_PORT
        );
        EventLocal.broker = await EventLocalInit();
        EventLocal.message = MessageLocalInit(this); 
        ApiLocalInit(app);

        await hl.activation();
        rl.on("SIGINT", async () => {
          await hl.deactivation();
          process.exit(0);
        });
        resolve(this);
      });
    });
  }
  sendEvent(q: string, m: string) {
    return EventLocal.broker.emit(q, m);
  }
  sendMessage(chatId: number, m: string) {
    return EventLocal.message.send(chatId, m);
  }

  sendApi(host, port, path): Promise<any> {
    return new Promise((resolve, rej) => {
      var req = http.get(
        {
          host: host,
          port: port,
          agent: false,
          path: path, 
        },
        function(res) {
          if (res.statusCode !== 200) {
            resolve(res);
          } else {
            res.on("data", d => {
              resolve(JSON.parse(d.toString("utf8")));
            });
          }
        }
      );
      req.on("error", function(e) {
        resolve(e);
      });
    });
  }
}
