// reeeper/cron/expire-crashed-hosts.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const path = require('path');

const mongoose = require('mongoose');
const NetHost = mongoose.model('NetHost');

const { CronJob } = require('cron');

const { SiteWorkerProcess } = require(path.join(__dirname, '..', '..', '..', '..', 'lib', 'site-lib'));

/**
 * Hosts on the DTP network register themselves and periodically report various
 * metrics. They clean up after themselves when exiting gracefully. But, hosts
 * lose power or get un-plugged or get caught in a sharknado or whatever.
 * 
 * When that happens, the Reeeper ensures those hosts don't become Night of the
 * Living Dead.
 * 
 * That is the formal technical explanation of what's going on in here. We're
 * preventing DTP host processes from becoming The Night of the Living Dead.
 */
class CrashedHostsCron extends SiteWorkerProcess {

  static get COMPONENT ( ) {
    return {
      name: 'crashedHostsCron',
      slug: 'crashed-hosts-cron',
    };
  }

  constructor (worker) {
    super(worker, CrashedHostsCron.COMPONENT);
  }

  async start ( ) {
    await super.start();

    await this.expireCrashedHosts(); // first-run the expirations

    this.job = new CronJob(
      '*/5 * * * * *',
      this.expireCrashedHosts.bind(this),
      null,
      true,
      process.env.DTP_CRON_TIMEZONE || 'America/New_York',
    );
  }

  async stop ( ) {
    if (this.job) {
      this.log.info('stopping host expire job');
      this.job.stop();
      delete this.job;
    }
    await super.stop();
  }

  async expireCrashedHosts ( ) {
    try {
      await NetHost
        .find({ status: 'crashed' })
        .select('_id hostname')
        .lean()
        .cursor()
        .eachAsync(async (host) => {
          this.log.info('deactivating crashed host', { hostname: host.hostname });
          await NetHost.updateOne({ _id: host._id }, { $set: { status: 'inactive' } });
        });
    } catch (error) {
      this.log.error('failed to expire crashed hosts', { error });
    }
  }
}

module.exports = CrashedHostsCron;