import * as http from 'http'

import * as express from 'express'
import * as cors from 'cors'
import * as bodyParser from 'body-parser'

import * as env from './env'

import {
  RobotUsecase,
  RobotUsecaseOptions
} from './usecase'

import {
  RobotManager,
  RobotManagerOptions
} from './manager'

import {
  HttpApi,
  HttpApiOptions
} from './interface/http-api'

import {
  RobotJSProvider,
  RobotJSProviderOptions
} from './provider'

function init (envConfig: any): http.Server {

  // Initialize robotjs as the robot provider.
  const robotjsProviderOptions = new RobotJSProviderOptions()
  const robotjsProvider = new RobotJSProvider(robotjsProviderOptions)

  // Initialize the robot manager.
  const robotManagerOptions = new RobotManagerOptions()
  const robotManager = new RobotManager(robotManagerOptions)
  robotManager.desktopRobot = robotjsProvider

  // Initialize the robot usecase.
  const robotUsecaseOptions = new RobotUsecaseOptions()
  const robotUsecase = new RobotUsecase(robotUsecaseOptions)
  robotUsecase.robotManager = robotManager

  // Initialize the http api.
  const httpApiOptions = new HttpApiOptions()
  httpApiOptions.appName = envConfig[env.ENV_APP_NAME]
  httpApiOptions.appDescription = envConfig[env.ENV_APP_DESCRIPTION]

  const h = new HttpApi(httpApiOptions)
  h.setRobotUsecase(robotUsecase)

  // Setup the router for directing requests to the http api.
  const router = express()
  router.use(h.mw.forceHTTPS.bind(h.mw))
  router.use(cors())
  router.use(bodyParser.json())
  router.get('/', h.meta.getIndex.bind(h.meta))

  // Declare the http api as version 0.
  const v0 = express()

  // v0.get('/robots/:rid/sensors')
  v0.get('/robot/sensor/screen.png',
    h.robotApi.getScreenImage.bind(h.robotApi))

  v0.post('/robot/actuator/mouse',
    bodyParser.urlencoded({ extended: true }),
    h.robotApi.moveMousePosition.bind(h.robotApi))

  v0.post('/robot/actuator/keybaord',
    bodyParser.urlencoded({ extended: true }))

  // Use the defined routers and start the server!
  router.use('/v0', v0)
  const server = http.createServer(router)
  server.on('error', (err: any) => {
    console.log(`Error running server: ${err}`)
  })
  server.on('listening', () => {
    console.log(`Listening on port: ${envConfig[env.ENV_PORT]}`)
  })

  return server
}

export default {
  init
}
