import {get, post, put, remove} from './apiHelpers.js'
import {convertList} from './adapter/adapter.js'
import {equals, cond} from "ramda";

/**
 * Интерфейс роутера
 * @typedef {Object} Router
 * @param {Number}  id
 * @param {Number}  server_id
 * @param {String}  path
 * @param {Number}  role
 * @param {String}  description
 * @param {Number}  deepness
 * @param {Number}  order
 * @param {Boolean} is_cb_on
 * @param {Number}  cb_request_limit
 * @param {Number}  cb_min_requests
 * @param {Number}  cb_error_threshold_percentage
 * @param {Number}  cb_interval_duration
 * @param {Number}  cb_open_state_timeout
 */

/**
 * Интерфейс роутера
 * @typedef {Object} Action
 * @property {'remove' | 'create' | 'update' | 'delete'} action
 *
 * @typedef {Router & Action} ActionRouter
 */

class Routes {

  /**
   * Класс управления роутерами
   * @param {String} apiAddr - path to service
   * @param {Object | undefined} adapter_config - oldKey: newKey
   */
  constructor(apiAddr, adapter_config = {}) {
    this.apiAddr = apiAddr
    this.config = adapter_config
  }

  /**
   *
   * @returns {Promise<*[]>}
   */
  async getRoutes() {
    let res = await get(`${this.apiAddr}/routers`)
    let updatedRoutes = convertList(res.data, {config: this.config})
    return updatedRoutes
  }

  /**
   *
   * @param {Number} id - Сервис id, если id не указан, отображается список всех роутеров
   * @returns {Promise<*[]>}
   */
  async getRouterById(id) {
    let res = await get(`${this.apiAddr}/routers/by_server/${id}`)
    let updatedRoutes = convertList(res.data, {config: this.config})
    return updatedRoutes
  }

  /**
   *
   * @param {Router} routerData
   * @returns {Promise<void>}
   */
  async createRoute(routerData) {
    const newRoute = await post(`${this.apiAddr}/routers`, routerData)
    return newRoute
  }

  /**
   *
   * @param {Router} routerData
   * @returns {Promise<void>}
   */
  async updateRoute(routerData) {
    const updatedRouterData = {...routerData}
    delete updatedRouterData.id
    const newRoute = await put(`${this.apiAddr}/routers/${routerData.id}`, updatedRouterData)
    return newRoute
  }

  /**
   *
   * @param {Number} routerId - Сервис id, если id не указан, отображается список всех роутеров
   * @returns {Promise<*[]>}
   */
  async removeRoute(routerId) {
    const removedRoute = await remove(`${this.apiAddr}/routers/${routerId}`)
    return removedRoute
  }

  /**
   *
   * @param {Array<ActionRouter>} routesActions - Группа роутеров для обновления
   * @returns {Promise<Array<Router>>}
   */
  async updateGroupRoutes(routesActions) {
    const responses = routesActions.map(async (mutation) => {
      return cond([
        [equals('create'), () => this.createRoute(mutation)],
        [equals('delete'), () => this.removeRoute(mutation.id)],
        [equals('remove'), () => this.removeRoute(mutation.id)],
        [equals('update'), () => this.updateRoute(mutation)],
      ])(mutation.action)
    })

    return Promise.all(responses)
  }

  /**
   * Функция запускает список запросов к апишке и логает ответы
   * @returns {Promise<String>}
   */
  async test() {
    console.log("_______START TEST_______")

    const allRoutes = await this.getRoutes()
    console.log("allRoutes", allRoutes)
    const serverRouter = await this.getRouterById(1)
    console.log("getRouterById 1", serverRouter)
    const newRoute = await this.createRoute({
      "server_id": 1,
      "path": "/",
      "role": 1,
      "description": "tests swagger",
      "deepness": 6,
      "order": 0,
      "is_cb_on": true,
      "cb_request_limit": 100,
      "cb_min_requests": 100,
      "cb_error_threshold_percentage": 0.35,
      "cb_interval_duration": 2000000,
      "cb_open_state_timeout": 1000000
    })
    console.log("newRoute", newRoute)
    const updatedRoute = await this.updateRoute({
      "path": "/updated_path/",
      "description": "updated_description",
      "id": newRoute.id
    })
    console.log("updatedRoute", updatedRoute)
    const removedRoute = await this.removeRoute(newRoute.id)
    console.log("removedRoute", removedRoute)

    const newRoute1 = await this.createRoute({
      "server_id": 1,
      "path": "/",
      "role": 1,
      "description": "tests swagger",
      "deepness": 6,
      "order": 0,
      "is_cb_on": true,
      "cb_request_limit": 100,
      "cb_min_requests": 100,
      "cb_error_threshold_percentage": 0.35,
      "cb_interval_duration": 2000000,
      "cb_open_state_timeout": 1000000
    })
    const newRoute2 = await this.createRoute({
      "server_id": 1,
      "path": "/",
      "role": 1,
      "description": "tests swagger",
      "deepness": 6,
      "order": 0,
      "is_cb_on": true,
      "cb_request_limit": 100,
      "cb_min_requests": 100,
      "cb_error_threshold_percentage": 0.35,
      "cb_interval_duration": 2000000,
      "cb_open_state_timeout": 1000000
    })
    const newRoute3 = await this.createRoute({
      "server_id": 1,
      "path": "/",
      "role": 1,
      "description": "tests swagger",
      "deepness": 6,
      "order": 0,
      "is_cb_on": true,
      "cb_request_limit": 100,
      "cb_min_requests": 100,
      "cb_error_threshold_percentage": 0.35,
      "cb_interval_duration": 2000000,
      "cb_open_state_timeout": 1000000
    })

    const actions = [
      {
        ...newRoute1,
        action: "update",
        "path": "/updated_path2/",
        "description": "updated_description2",
      }, {
        ...newRoute2,
        action: "update",
        "path": "/updated_path3/",
        "description": "updated_description3",
      }, {
        ...newRoute3,
        action: "remove"
      },
      {
        action: "create",
        "server_id": 1,
        "path": "/lalalala/lalalal",
        "role": 1,
        "description": "new_route_created",
        "deepness": 6,
        "order": 0,
        "is_cb_on": true,
        "cb_request_limit": 100,
        "cb_min_requests": 100,
        "cb_error_threshold_percentage": 0.35,
        "cb_interval_duration": 2000000,
        "cb_open_state_timeout": 1000000
      }
    ]

    const mutationsList = await this.updateGroupRoutes(actions)
    console.log("mutationsList", mutationsList)
    console.log("________END TEST________")

    return "ok"
  }
}

export default Routes