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

import { checkDomain, doSomething, getValidity } from '@things-factory/operato-license-checker'
import { Domain } from '@things-factory/shell'

import { LicenseError } from '../errors/license-error'
import { DomainSecret } from '../service/domain-secret/domain-secret'

@EventSubscriber()
export class DomainSubscriber implements EntitySubscriberInterface<Domain> {
  listenTo() {
    return Domain
  }
  /**
   * Called before domain insertion.
   */
  async afterInsert(event: InsertEvent<Domain>) {
    var entityManager = event.manager

    if (getValidity()) {
      //1. check domain count is over licensed quantity or not
      var domain: Domain = event.entity
      var count =
        (await entityManager
          .createQueryBuilder()
          .select('domain')
          .from(DomainSecret, 'secret')
          .where('domain_id = :domainId', { domainId: domain.id })
          .getCount()) + 1

      //2. create new token to domain and save domain-secret
      if (checkDomain(count)) {
        var domain: Domain = event.entity
        var domainSecret: DomainSecret = new DomainSecret()
        domainSecret.id = uuidv4()
        domainSecret.domain = domain.domain
        var hash = doSomething({ secId: domainSecret.id, id: domain.id })
        domainSecret.secret = hash

        await entityManager.save(domainSecret)
      } else {
        throw new LicenseError({
          errorCode: LicenseError.ERROR_CODES.VERIFICATION_ERROR
        })
      }
    }
  }
  /**
   * Called after entity is removed.
   */
  async afterRemove(event: RemoveEvent<Domain>) {
    var entityManager = event.manager
    await entityManager.query(
      `delete 
             from domain_secrets
            where domain_id not in (select id from domains)`
    )
  }
}
