import * as plugins from '../plugins.js';
import * as paths from '../paths.js';
import { logger } from './logging.js';

import { JwtManager } from './classes.jwtmanager.js';
import { LoginSessionManager } from './classes.loginsessionmanager.js';
import { RegistrationSessionManager } from './classes.registrationsessionmanager.js';
import { ReceptionDb } from './classes.receptiondb.js';
import { ReceptionMailer } from './classes.receptionmailer.js';
import { UserManager } from './classes.usermanager.js';
import { ApiTokenManager } from './classes.apitokenmanager.js';
import { ReceptionHousekeeping } from './classes.housekeeping.js';
import { OrganizationManager } from './classes.organizationmanager.js';
import { RoleManager } from './classes.rolemanager.js';
import { BillingPlanManager } from './classes.billingplanmanager.js';

export interface IReceptionOptions {
  /**
   * a name for the idp instance.
   */
  name: string;
  mongoDescriptor: plugins.smartdata.IMongoDescriptor;
  websiteServer: plugins.typedserver.utilityservers.UtilityWebsiteServer;
  baseUrl: string;
}

export class Reception {
  public projectinfoNpm = new plugins.projectinfo.ProjectinfoNpm(paths.packageDir);
  public typedrouter = new plugins.typedrequest.TypedRouter();
  public serviceQenv = new plugins.qenv.Qenv('./', './.nogit');
  public szPlatformClient = new plugins.szPlatformClient.SzPlatformClient();
  public db = new ReceptionDb(this);

  // managers
  public jwtManager = new JwtManager(this);
  public loginSessionManager = new LoginSessionManager(this);
  public registrationSessionManager = new RegistrationSessionManager(this);
  public apitokenManager = new ApiTokenManager(this);
  public receptionMailer = new ReceptionMailer(this);
  public userManager = new UserManager(this);
  public organizationmanager = new OrganizationManager(this);
  public roleManager = new RoleManager(this);
  public billingPlanManager = new BillingPlanManager(this);
  housekeeping = new ReceptionHousekeeping(this);

  constructor(public options: IReceptionOptions) {
    if (!options.mongoDescriptor) {
      throw new Error('mongoDescriptor is required');
    }
    if (!options.websiteServer) {
      throw new Error('websiteServer is required');
    }
  }

  /**
   * starts the reception instance
   */
  public async start() {
    await this.szPlatformClient.init(await this.serviceQenv.getEnvVarOnDemand('SERVEZONE_PLATFROM_AUTHORIZATION'));
    logger.log('info', 'starting reception');
    logger.log('info', 'adding typedrouter to website server');
    this.options.websiteServer.typedrouter.addTypedRouter(this.typedrouter);
    logger.log('info', 'starting database');
    await this.db.start();
    await this.jwtManager.start();
  }

  /**
   * stops the reception instance
   */
  public async stop() {
    await this.housekeeping.stop();
    console.log('stopped serviceserver!');
    await this.db.stop();
  }
}
