import pg = require('pg');
// import PromisePool = require('es6-promise-pool');
import * as Aggregator from './models/Aggregators';
import { RedshiftResult } from './types/redshift';
import { InfluxClient as influx } from './influx';
import { IPoint } from 'influx/lib/src';

// VERY Important for Postgres time translation
process.env.TZ = 'America/Los_Angeles'

const config: pg.ClientConfig = {
  host: 'tahoe-replica.cpe.wtf',
  port: 5439,
  user: 'administrator',
  password: process.env.TAHOE_REPLICA_PASS,
  ssl: true,
  database: 'product'
};

const client = new pg.Client(config);
class Blink {
  public static async main(): Promise<number> {

    console.log(JSON.stringify(process.argv, null, 2));

    await client.connect();

    // console.log(BceByClientKeyDestinationIsapplaunchCountry.query);

    let data: RedshiftResult[];

    if (process.env.BLINK_MODE === 'test') {
      data = require(`../test_data.json`)
    } else {
      let query: string = (Aggregator[process.argv[2]]).query(process.argv[3]) 
      data = (await client.query(query)).rows;
    }

    await client.end()

    // console.log(JSON.stringify(data, null, 2));

    let out = data.map(d => {
      return (new (Aggregator[process.argv[2]])(d)).toInflux();
    })

    // console.log(JSON.stringify(out, null, 2));

    const database = 'latency_portal';

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

    console.log(`Writing ${batches} batches of 10000`)

    let pool: Promise<void>[] = [];
  
    if (process.env.BLINK_MODE !== 'test') {
      for (let i = 0; i < out.length; i += batchSize) {
        console.log(`Submitting points ${i} to ${i+batchSize}`)
        try {
          
          pool.push(influx.writePoints(out.slice(i, i + batchSize), {database: database, retentionPolicy: '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 ${out.length}.`);
            }
          }).catch((err: any) => {
            console.error(`Error saving data to InfluxDB! ${err.stack}`);
          }));

        } catch (err) {
          console.log(err);
        }

        if (pool.length == 20) {
          await Promise.all(pool);
          pool = [];
        }

      }
    } else {
      console.log(JSON.stringify(data, null, 2));
    }

    await Promise.all(pool);
    return 0;
  }

}

Blink.main().then(r => {
  process.exit(r);
}).catch(e => {
  console.log(e);
  process.exit(1);
})