#!/usr/bin/python

import os
import sys
import posixpath
import filecmp
import shutil

from subprocess import Popen, PIPE

DEFAULT_DIR = '/tmp/checkbox.optical'
DEFAULT_DEVICE_DIR = 'device'
DEFAULT_IMAGE_DIR = 'image'


CDROM_ID = '/lib/udev/cdrom_id'

def _command(command, shell=True):
    proc = Popen(command,
                   shell=shell,
                   stdout=PIPE,
                   stderr=PIPE
                   )
    return proc

def _command_out(command, shell=True):
    proc = _command(command, shell)
    return proc.communicate()[0].strip()

def compare_tree(source, target):
    for dirpath, dirnames, filenames in os.walk(source):
        #if both tree are empty return false
        if dirpath == source and dirnames == [] and filenames == []:
            return False
        for name in filenames:
            file1 = os.path.join(dirpath, name)
            file2 = file1.replace(source, target, 1)
            if os.path.isfile(file1) and not os.path.islink(file1):
                if filecmp.cmp(file1, file2):
                    continue
                else:
                    return False
            else:
                continue
    return True

def read_test(device):
    passed = False
    device_dir = os.path.join(DEFAULT_DIR, DEFAULT_DEVICE_DIR)
    image_dir = os.path.join(DEFAULT_DIR, DEFAULT_IMAGE_DIR)

    for dir in (device_dir, image_dir):
        if posixpath.exists(dir):
            shutil.rmtree(dir)
    os.makedirs(device_dir)

    try:
        _command("umount %s" % device).communicate()
        mount = _command("mount -o ro %s %s" % (device, device_dir))
        mount.communicate()
        if mount.returncode != 0:
            return False

        _command("cp -dpR %s %s" % (device_dir, image_dir)).communicate()
        if compare_tree(device_dir, image_dir):
            passed = True
    except:
        passed = False
    finally:
        _command("umount %s" % device_dir).communicate(3)
        for dir in (device_dir, image_dir):
            if posixpath.exists(dir):
                shutil.rmtree(dir)

    if passed:
        print "Passed"
    else:
        print "Failed"
    return passed


def get_capabilities(device):
    cmd = "%s %s" % (CDROM_ID, device)
    capabilities = _command_out(cmd)
    return capabilities.split('\n')

def main(args):
    tests = []
    return_values = []

    for device in args:
        capabilities = get_capabilities(device)
        for capability in capabilities:
            if capability[:3] == 'ID_':
                cap = capability[3:-2]
                if cap == 'CDROM' or cap == 'CDROM_DVD':
                    tests.append('read')

        for test in set(tests):
            sys.stdout.write("Testing %s on %s ... " % (test, device))
            tester = "%s_test" % test
            return_values.append(globals()[tester](device))
            sys.stdout.flush()

    return False in return_values

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

