import { RedshiftResult } from "../types/redshift";
import { InfluxTags, InfluxFields } from "../types/influx";
import { IPoint } from "influx/lib/src";
const country_names = require('../data/country_names.json');

export class DataPoint {

  destination_db: string;
  measurement: string;

  groups: string[];
  manual_groups: string[] = [];

  percentiles: number[];

  raw_data: RedshiftResult;

  constructor(data: RedshiftResult) {
    this.raw_data = data;
    this.raw_data.country = country_names[data.country] ? country_names[data.country] : `Unknown Country Code - ${data.country}`; 
  }

  getTags(): InfluxTags {
    let t:InfluxTags = {}

    this.groups.map(g => {
      t[g] = String(this.raw_data[g])
    })

    this.manual_groups.map(g => {
      t[g] = String(this.raw_data[g])
    })
    
    return t;
  }

  getFields(): InfluxFields {
    let f:InfluxFields = {
      count: +this.raw_data.count
    }

    this.percentiles.map(p => {
      f[`duration_tp${p}`] = +this.raw_data[`duration_tp${p}`]
      f[`tp${p}Weight`] = +(+this.raw_data[`duration_tp${p}`] * +this.raw_data.count)
    })

    return f;
  }

  filteredTags(): InfluxTags {
    const originals = this.getTags()
    const filtered: InfluxTags = {}

    for (let key in originals) {
      switch (originals[key]) {
        case '':
        case undefined:
        case null:
          continue;
        case 'null':
          continue;
        default:
          filtered[key] = originals[key].replace(/\\/g, '')
      }
    }

    return filtered
  }

  filteredFields(): InfluxFields {
    const originals = this.getFields()
    const filtered: InfluxFields = {}

    for (let key in originals) {
      switch (originals[key]) {
        case undefined:
          continue;
        default:
          if (typeof (originals[key]) != "string" && typeof (originals[key]) != "boolean" && isNaN(+originals[key])) {
            filtered[key] = 0;
          } else {
            filtered[key] = originals[key];
          }
      }
    }

    return filtered
  }

  public print(): void {
    console.log(this.measurement);
    console.log(this.groups);
    console.log();
  }

  toInflux(): IPoint {
    const data = {
      measurement: this.measurement,
      timestamp: new Date(this.raw_data.day).getTime() * 1000000,
      tags: this.filteredTags(),
      fields: this.filteredFields()
    }

    return data;
  }

}