// I'm dumb and ECS doesn't have tags, although it's marked taggable in Litany :(
// Leaving the code here because it was hard to do...

import AWS = require('aws-sdk');
import { Cacher } from './base';
import { NamespaceCache } from '../../interfaces/tagcache';
import { SensuTagSet } from '../../interfaces/sensu';

export class ECSTags extends Cacher {

    // AWS/ECS
    // - ClusterName: services
    // - ServiceName: tempo
    ecs: AWS.ECS;

    constructor() {
        super()
        this.ecs = new AWS.ECS();
    }

    public get(dimensions: AWS.CloudWatch.Types.Dimensions, cache: NamespaceCache): SensuTagSet {
        let d = this.mergeDimensions(dimensions);
        return {};

        // let clusterTags = [];
        // let serviceTags = [];

        // if (d.ClusterName) {
        //   clusterTags = [].concat.apply([], cache.Dimension.Clusters.filter(t => {
        //     return (t.clusterName === d.ClusterName);
        //   }).map(t=> {return t.Tags}))
        // }

        // if (d.ServiceName) {
        //   serviceTags = [].concat.apply([], cache.Dimension.Services.filter(t => {
        //     return (t.serviceName === d.ServiceName);
        //   }).map(t=> {return t.Tags}))
        // }

        // return this.mergeTags([].concat(clusterTags, serviceTags))
    }

    public async fill() {

        let clusterServices: { ClusterName: string, Tags: {}[], Services: { ServiceName: string, Tags: {}[] }[] }[] = [];
        let clusterTagPromises: Promise<AWS.ECS.DescribeClustersResponse>[] = [];
        let serviceTagPromises: Promise<AWS.ECS.DescribeServicesResponse[]>[] = [];

        // Wait for list of clusters
        await new Promise((resolve, reject) => {
            this.ecs.listClusters().eachPage((err: any, data) => {
                if (err) {
                    console.log(err);
                    reject();
                    return false;
                }

                if (data === null) {
                    resolve();
                    return true;
                }

                for (let cluster of data.clusterArns) {
                    clusterServices.push({ ClusterName: cluster, Tags: [], Services: [] });
                }
                return true;
            });
        });

        clusterTagPromises.push(
            this.ecs.describeClusters({ clusters: clusterServices.map(c => { return c.ClusterName }) }).promise()
        );

        for (let cluster of clusterServices) {
            serviceTagPromises.push(
                new Promise((resolve, reject) => {
                    let serviceArns: { ServiceName: string, Tags: {}[] }[] = [];
                    this.ecs.listServices({ cluster: cluster.ClusterName }).eachPage((err: any, data) => {
                        if (err) {
                            console.log(err);
                            reject();
                            return false;
                        }

                        if (data === null) {
                            resolve();
                            return true;
                        }

                        for (let service of data.serviceArns) {
                            serviceArns.push({ ServiceName: service, Tags: [] });
                        }
                        return true;
                    });
                }).then(() => {
                    let batchPromises: Promise<AWS.ECS.DescribeServicesResponse>[] = [];
                    const batchSize = 10;
                    const serviceBatches = Math.ceil(cluster.Services.length / batchSize);

                    for (let i = 0; i < serviceBatches; i++) {
                        const serviceSlice = cluster.Services.slice(i * batchSize, (i * batchSize) + batchSize);
                        const params = {
                            cluster: cluster.ClusterName,
                            services: serviceSlice.map(s => s.ServiceName)
                        }
                        batchPromises.push(this.ecs.describeServices(params).promise());
                    }
                    return Promise.all(batchPromises);
                })
            )
        }

        await Promise.all([clusterTagPromises, serviceTagPromises]).then(data => {
            let clusterResponse = data[0];
            let serviceResponse = data[1];
            console.log(JSON.stringify(data, null, 2));
        });

        return new Promise((r, re) => {
            let cache: NamespaceCache = {
                LastUpdated: new Date(),
                Dimension: { Clusters: [] }
            }
            r(cache);
        }) as Promise<NamespaceCache>;
    }
}
