import {Duniter} from 'duniter';
import {gvaHttpListen} from "./src/network";
import * as Http from "http";
import {UpnpProvider} from "duniter/app/modules/upnp-provider";

const DEFAULT_GVA_PORT = 15000

Duniter.run([{
  name: 'gva',
  required: {
    duniter: {

      cliOptions: [
        { value: '--gva-port <port>',     desc: 'Force usage of a specific port for GVA.', parser: (val: string) => parseInt(val) },
        { value: '--gva-host <porthost>', desc: 'Force usage of a specific host for GVA.' },
        { value: '--gva-upnp',            desc: 'Use UPnP for port opening.' },
        { value: '--gva-noupnp',          desc: 'Do not use UPnP for port opening.' },
      ],

      config: {
        onLoading: (conf: any, program: any) => {
          if (program.gvaPort || program.gvaHost || program.noupnp || program.upnp) {
            if (!conf.gva) {
              conf.gva = {}
            }
            if (program.gvaPort) {
              conf.gva.port = program.gvaPort
            }
            if (program.gvaHost) {
              conf.gva.host = program.gvaHost
            }
            if (program.noupnp) {
              conf.gva.upnp = false
            }
            if (program.upnp) {
              conf.gva.upnp = true
            }
          }
        },
        beforeSave: (conf, program, logger, confDAL) => {
        }
      },

      cli: [{
        name: 'gva',
        desc: 'Starts the UI',
        onDatabaseExecute: async (server, conf, program, params, start, stop) => {
          // Never ending
          await new Promise(async (res, rej) => {
            try {
              const { available, host, port } = { available: true, host: 'localhost', port: 15000 }
              // const { available, host, port } = await api.startRegular()
              if (available) {
                gvaHttpListen(server, port, host)
              }
            } catch (e) {
              rej(e)
            }
          })
        }
      }],
      service: {
        neutral: (server, conf: any) => {

          let app: Http.Server|undefined
          let api = new UpnpProvider(
            (conf.gva && conf.gva.port) || DEFAULT_GVA_PORT,
            (conf.gva && conf.gva.port) || DEFAULT_GVA_PORT + 1000,
            ':gva:' + conf.pair.pub.substr(0, 6))
          return {
            startService: async () => {
              if (conf.gva) {
                // Static usage of port + host, no UPnP
                app = gvaHttpListen(server,
                  conf.gva.port || DEFAULT_GVA_PORT,
                  conf.gva.host || 'localhost')
              }
              else if (!conf.gva || conf.gva.upnp) {
                // Using UPnP
                const { available, host, port } = await api.startRegular()
                if (available) {
                  app = gvaHttpListen(server, port, host)
                }
              } else if (!conf.gva) {
                // Static usage of port + host, no UPnP
                app = gvaHttpListen(server, DEFAULT_GVA_PORT)
              }
            },
            stopService: async () => {
              await new Promise(res => app && app.close(res))
              await (api && api.stopRegular())
            }
          } as any
        }
      }
    }
  }
}])