#!/usr/bin/env python

import sys, os, time
import rrdtool
import whisper
from optparse import OptionParser

option_parser = OptionParser(usage='''%prog rrd_path''')
option_parser.add_option('--xFilesFactor', default=0.5, type='float')

(options, args) = option_parser.parse_args()

if len(args) < 1:
  option_parser.print_usage()
  sys.exit(1)

rrd_path = args[0]

rrd_info = rrdtool.info(rrd_path)

seconds_per_point = rrd_info['step']

# First get the max retention - we grab the max of all datasources
if 'rra' in rrd_info:
  rras = rrd_info['rra']
else:
  rra_count = max([ int(key[4]) for key in rrd_info if key.startswith('rra[') ]) + 1
  rras = [{}] * rra_count
  for i in range(rra_count):
    rras[i]['pdp_per_row'] = rrd_info['rra[%d].pdp_per_row' % i]
    rras[i]['rows'] = rrd_info['rra[%d].rows' % i]

retention_points = 0
for rra in rras:
  points = rra['pdp_per_row'] * rra['rows']
  if points > retention_points:
    retention_points = points

retention = seconds_per_point * points

datasources = []
if 'ds' in rrd_info:
  datasource_names = rrd_info['ds'].keys()
else:
  ds_keys = [ key for key in rrd_info if key.startswith('ds[') ]
  datasources = list(set( key[3:].split(']')[0] for key in ds_keys ))

for datasource in datasources:
  now = int( time.time() )
  path = rrd_path.replace('.rrd','_%s.wsp' % datasource)
  whisper.create(path, [(seconds_per_point,retention_points)], xFilesFactor=options.xFilesFactor)
  size = os.stat(path).st_size
  print 'Created: %s (%d bytes)' % (path,size)

  print 'Migrating data'
  startTime = str(now - retention)
  endTime = str(now)
  (time_info,columns,rows) = rrdtool.fetch(rrd_path, 'AVERAGE', '-s', startTime, '-e', endTime)
  column_index = list(columns).index(datasource)
  rows.pop() #remove the last datapoint because RRD sometimes gives funky values

  values = [row[column_index] for row in rows]
  timestamps = list(range(*time_info))
  datapoints = zip(timestamps,values)
  datapoints = filter(lambda p: p[1] is not None, datapoints)
  print ' migrating %d datapoints...' % len(datapoints)
  whisper.update_many(path, datapoints)
