#!/usr/bin/env python

import os, sys, re, subprocess, glob

def usage(success = True):
    out = sys.stdout if success else sys.stderr

    print >> out, 'Usage: %s [ssd|hdd] [raid0|single|justdel]' % sys.argv[0]
    print >> out
    print >> out, 'This script will delete the SSD/HDD RAID configuration and then make a new one,'
    print >> out, 'either as N separate devices or as one RAID 0 device.'
    print >> out
    print >> out, 'WARNING: Do not run this script if there is anything important on the drives;'
    print >> out, '         it will be deleted.'
    print >> out
    print >> out, 'Note: This script is fairly hard-wired; for instance, it assumes that c5 is'
    print >> out, '      assigned to the SSDs and c6 is assigned to the HDDs.'

    exit(0 if success else 2)

def log(msg):
    # This program should print only the newly-created device names.
    pass

def get_devs():
    return set(glob.glob('/dev/sd?'))

def run_cmd(*args):
    assert args # Empty list would start interactive shell.
    log('Running command: %s' % ' '.join(args))
    p = subprocess.Popen(('tw_cli',) + args, stdout=subprocess.PIPE)
    out, err = p.communicate()
    if p.poll() == 0:
        return out
    else:
        raise RuntimeError, 'run_cmd failed with status %r' % (p.poll())

def get_ids(prefix, out):
    ids = []
    for line in out.split('\n'):
        m = re.match(r'^(%s\d+)' % prefix, line)
        if m:
            ids.append(m.groups()[0])
    return ids

def del_units(controller):
    ids = get_ids('u', run_cmd('/%s show' % controller))
    if not ids:
        log('(Not deleting existing units because none exist.)')
        return
    units = ['/%s/%s' % (controller, id) for id in ids]
    log('Deleting %r' % units)
    for unit in units:
        run_cmd('%s del quiet' % unit)

def mk_units(controller, mode):
    # Sanity check, really.
    ports = get_ids('p', run_cmd('/%s show' % controller))
    ports = [p[1:] for p in ports] # Get rid of the initial 'p'.
    assert sorted(ports) == ['0','1','2','3']

    if mode == 'raid0':
        #run_cmd('/%s add type=raid0 disk=%d-%d' % (controller, min(ports), max(ports)))
        run_cmd('/%s add type=raid0 disk=%s' % (controller, ':'.join(ports)))
    elif mode == 'single':
        for port in ports:
            run_cmd('/%s add type=single disk=%s' % (controller, port))

def init():
    if len(sys.argv) != 3:
        usage(False)

    if os.getuid() != 0:
        # Alternative: Have this script run `sudo tw_cli`.
        print >> sys.stderr, "This program must be run as root."
        sys.exit(3)

    controllers = {'ssd': 'c5', 'hdd': 'c6'}

    try: controller = controllers[sys.argv[1]]
    except KeyError, e:
        usage(False)

    mode = sys.argv[2]
    if mode not in ['single', 'raid0', 'justdel']:
        usage(False)

    # Sanity check.
    assert sorted(get_ids('c', run_cmd('show'))) == sorted(controllers.values())

    return (controller, mode)


def main():
    (controller, mode) = init()

    del_units(controller)

    devs_before = get_devs()
    mk_units(controller, mode)
    devs_after = get_devs()

    for dev in sorted(devs_after - devs_before):
        print dev

if __name__ == '__main__':
    main()
