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

export class RDSTags extends Cacher {

  rds: AWS.RDS;

  constructor() {
    super()
    this.rds = new AWS.RDS();
  }

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

    let clusterTags: AWSTagSet = [];
    let instanceTags: AWSTagSet = [];

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

    if (d.DBInstanceIdentifier) {
      instanceTags = [].concat.apply([], cache.Dimension.Instances.filter(t => {
        return (t.DBInstanceIdentifier === d.DBInstanceIdentifier);
      }).map(t => { return t.Tags }))
    }

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

  public async fill() {

    let clusters: { DBClusterIdentifier: string, Tags: AWSTagSet }[] = [];
    let instances: { DBInstanceIdentifier: string, Tags: AWSTagSet }[] = [];

    let clusterTagPromise: Promise<void[]> = this.rds.describeDBClusters().promise().then(data => {
      return Promise.all(data.DBClusters.map((cluster) => {
        return this.rds.listTagsForResource({ ResourceName: cluster.DBClusterArn }).promise().then(tags => {
          clusters.push({ DBClusterIdentifier: cluster.DBClusterIdentifier, Tags: tags.TagList as AWSTagSet })
        })
      }))
    })

    let instanceTagPromise: Promise<void[]> = this.rds.describeDBInstances().promise().then(data => {
      return Promise.all(data.DBInstances.map((instance) => {
        return this.rds.listTagsForResource({ ResourceName: instance.DBInstanceArn }).promise().then(tags => {
          instances.push({ DBInstanceIdentifier: instance.DBInstanceIdentifier, Tags: tags.TagList as AWSTagSet })
        })
      }))
    })

    return Promise.all([clusterTagPromise, instanceTagPromise]).then(() => {
      let cache: NamespaceCache = {
        LastUpdated: new Date(),
        Dimension: {
          Clusters: clusters,
          Instances: instances,
        }
      };
      return cache;
    });
  }
}
