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

export class ElastiCacheTags extends Cacher {

  elasticache: AWS.ElastiCache;

  constructor() {
    super()
    this.elasticache = new AWS.ElastiCache();
  }

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

    ecTags = [].concat.apply([], cache.Dimension.Clusters.filter(t => {
      return (t.CacheClusterId === d.CacheClusterId);
    }).map(t => { return t.Tags }))

    return this.mergeTags(ecTags);
  }

  public async fill() {

    let clusters: { CacheClusterId: string, Tags: AWSTagSet }[] = [];
    let tagPromises: Promise<void>[] = [];

    await new Promise((resolve, reject) => {
      this.elasticache.describeCacheClusters().eachPage((err: any, data) => {
        if (err) {
          console.log(err);
          reject();
          return false;
        }

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

        for (let cluster of data.CacheClusters) {
          clusters.push({ CacheClusterId: cluster.CacheClusterId, Tags: [] });
        }
        return true;
      });
    });

    for (let cluster of clusters) {
      let arn = this.arn_builder('elasticache', 'cluster:' + cluster.CacheClusterId)
      tagPromises.push(this.elasticache.listTagsForResource({ ResourceName: arn }).promise().then(data => {
        cluster.Tags = data.TagList as AWSTagSet;
      }))
    }

    return Promise.all(tagPromises).then(() => {
      let cache: NamespaceCache = {
        LastUpdated: new Date(),
        Dimension: {
          Clusters: clusters,
        }
      };
      return cache;
    });
  }
}
