import AWS = require('aws-sdk');
import pako = require('pako');
import { SensuMetricStructure, SensuResult } from '../interfaces/sensu'

export class SNSHelpers {
    static sns: AWS.SNS = new AWS.SNS();

    public static async submitToSNS(metrics: SensuMetricStructure[]): Promise<AWS.SNS.PublishResponse[]> {
        const batchSize = 2000;
        console.info(`Discovered ${metrics.length} data points, submitting ${batchSize} at a time`);
        const batches = Math.ceil(metrics.length / batchSize);

        let batchPromises: Promise<AWS.SNS.PublishResponse>[] = [];

        for (let i = 0; i < metrics.length; i += batchSize) {
            console.log(`Submitting points ${i} to ${i + batchSize}`);
            let metricSlice = metrics.slice(i, i + batchSize);
            batchPromises.push(this.snsPublish(this.sensuWrapper(metricSlice)));
        }

        return Promise.all(batchPromises);
    }

    private static sensuWrapper(metrics: SensuMetricStructure[]) {
        let date = Math.round((new Date()).getTime() / 1000);
        let sensuResult: SensuResult = {
            client: "cloudwatch-" + process.env.PROJECT + "-" + process.env.STAGE,
            check: {
                type: "metric",
                status: 0,
                ttl: 900,
                interval: 60,
                name: process.env.AWS_REGION + "-metrics",
                awsAccountId: process.env.AWSAccountId,
                stage: process.env.STAGE,
                region: process.env.AWS_REGION,
                environment: process.env.PROJECT,
                issued: date,
                executed: date,
                timestamp: date,
                output: this.compressMetrics(metrics),
                handlers: ["charon-relay"]
            }
        }
        return sensuResult;
    }

    private static compressMetrics(metrics: SensuMetricStructure[]) {
        return new Buffer(pako.deflate(JSON.stringify(metrics), { to: 'string' })).toString('base64');
    }

    private static async snsPublish(result: SensuResult): Promise<AWS.SNS.PublishResponse> {
        let params = {
            Message: JSON.stringify(result),
            TopicArn: this.sns_arn(),
            MessageAttributes: {
                pipe: {
                    DataType: "String",
                    StringValue: "results"
                },
                type: {
                    DataType: "String",
                    StringValue: "direct"
                }
            }
        };

        return this.sns.publish(params).promise();
    }

    private static sns_arn(): string {
        return 'arn:aws:sns:' + process.env.AWS_REGION + ':' + process.env.AWSAccountId + ':sensu_ingress'
      };

}
