import { EntitySubscriberInterface, EventSubscriber, InsertEvent, RemoveEvent } from 'typeorm'
import { v4 as uuidv4 } from 'uuid'

import { Board } from '@things-factory/board-service'
import { checkTarget, doSomething, getValidity } from '@things-factory/operato-license-checker'

import { LicenseError } from '../errors/license-error'
import { BoardSecret } from '../service/board-secret/board-secret'

@EventSubscriber()
export class BoardSubscriber implements EntitySubscriberInterface<Board> {
  listenTo() {
    return Board
  }
  /**
   * Called before board insertion.
   */
  async afterInsert(event: InsertEvent<Board>) {
    var entityManager = event.manager
    if (getValidity()) {
      //target
      //1. check board count is over licensed quantity or not
      var board: Board = event.entity
      var domain: any = event.entity.domain
      var count =
        (await entityManager
          .createQueryBuilder()
          .select('board')
          .from(BoardSecret, 'secret')
          .where('domain_id = :domainId', { domainId: domain.id })
          .getCount()) + 1

      //2. create new token to board and save board-secret
      if (checkTarget(count)) {
        var board: Board = event.entity
        var boardSecret: BoardSecret = new BoardSecret()
        boardSecret.id = uuidv4()
        boardSecret.targetId = board.id
        boardSecret.targetType = 'board'
        boardSecret.domain = board.domain

        var hash = doSomething({ secId: boardSecret.id, id: board.id })
        boardSecret.secret = hash

        await entityManager.save(boardSecret)
      } else {
        throw new LicenseError({
          errorCode: LicenseError.ERROR_CODES.OVER_LIMIT
        })
      }
    }
  }

  /**
   * Called after entity is removed.
   */
  async afterRemove(event: RemoveEvent<Board>) {
    var entityManager = event.manager
    await entityManager.query(
      `delete 
             from board_secrets
            where target_id not in (select id from boards)`
    )
  }
}
