import { SensuEvent } from './models/SensuEvent';
import { DataPoint } from './models/DataPoint';
import { InfluxClient as influx } from './influx';
import { ArcanaClient } from "@twitch/arcana";

const arcana = new ArcanaClient();
let password: string;

async function getSecret() {
  password = password || await arcana.decryptAndTrim('influx_password'); 
}

export default async function processRecords(event: any, context: any, callback: any) {

  await getSecret();

  if (!password) {
    throw new Error("Unable to get password")
  }

  const sensuEvents: SensuEvent[] = event.Records.map((record: any) => new SensuEvent(record.kinesis.data));
  const dataPoints: DataPoint[] = [].concat.apply([], sensuEvents.map((event: SensuEvent) => event.dataPoints));
  const points = dataPoints.map((dataPoint: DataPoint) => dataPoint.toInflux());
  const batchSize = 10000;
  console.info(`Discovered ${points.length} data points, submitting ${batchSize} at a time`);

  let batch_success: number = 0;
  const batches: number = Math.ceil(points.length / batchSize);

  for (let i = 0; i < points.length; i += batchSize) {
    console.log(`Submitting points ${i} to ${i+batchSize}`)
    try {
      influx(password).writePoints(points.slice(i, i + batchSize), {retentionPolicy: 'raw_statistics'}).then(() => {
        console.log(`Done submitting ${i} to ${i+batchSize}. Currently ${batch_success} of ${batches} successful batches.`);

        batch_success++;
        if (batch_success >= batches) {
          console.info(`Successfully saved ${points.length}.`);
          callback(null, `Processed ${points.length} data points.`);
        }
      }).catch((err: any) => {
        console.error(`Error saving data to InfluxDB! ${err.stack}`);
        callback(err, null);
      });
    } catch (err) {
      console.log(err);
    }
    // await new Promise(resolve => setTimeout(resolve, 2500));
  }
}
