#!/usr/bin/env python2.7
import sys
import os
import re
import subprocess

import debian.deb822

def validate_ids(ids):
    usb_pci_ids_pattern = re.compile("^('[0-9a-f]{4}:[0-9a-f*]{0,4}' *)*'[0-9a-f]{4}:[0-9a-f*]{0,4}'$")
    if usb_pci_ids_pattern.match(ids):
        return True
    else:
        return False
        
def validate_apply_usb_pci_ids(package):
    if "usbid" in package or "pciid" in package:
        if package['apply'] != "usbid" and package['apply'] != "pciid":
            print package
            print "Error: apply type: %s" % package['apply']
            raise Exception
        if package['type'] != "task-apt-install":
            print package
            print "Error: Type: %s, Type should be task-apt-install" % package['type']
        if "usbid" in package:
            if validate_ids(package['usbid']):
                #print "apply==> %s, %s" % (package['usbid'], package['package'])
                pass
            else:
                print package
                print "\n%s: usbid not validate" % package['usbid']
                raise Exception
        if "pciid" in package:
            if validate_ids(package['pciid']):
                #print "apply==> %s, %s" % (package['pciid'], package['package'])
                pass
            else:
                print package
                print "\n%s: pciid not validate" % package['pciid']
                raise Exception

def verifysyntax(package):
    if not package:
        return False #ignore and end of the loop
    validate_apply_usb_pci_ids(package)
    return True
    
def pretty_apt_install_name(package):
    package_names = " ".join([ x.strip("\n\t ") for x in package['package'].split(",")])
    return package_names
    
def convert_package(aptoption,package,type,convert_file):
    install_pacakge(aptoption,package,type,convert_to_script=True,convert_file=convert_file)
    
def install_pacakge(aptoption,package,type,convert_to_script=False,convert_file=""):
    if type == "server-chroottask-apt-install":
        if package['type'] == "server-chroottask-apt-install":
            package_names = pretty_apt_install_name(package)
            cmd = "apt-get %s %s" % (aptoption, package_names)
            if (convert_to_script):
                convert_file.write(cmd + "\n")
            else:
                subprocess.check_call(cmd, shell=True)
    if type == "task-apt-install":
        if package['type'] == "task-apt-install":
            print package['package']

def parse_packageslist(aptoption, packagefilelist,action="verify",type="server-chroottask-apt-install",convert_file=""):
    with open(packagefilelist) as f:
        while True:
            package = debian.deb822.Deb822(f)
            if not verifysyntax(package):
                break
            if action == "install":
                install_pacakge(aptoption,package,type)
            if action == "convert":
                convert_package(aptoption,package,type,convert_file)

def install_packageslist(aptoption, packagefilelist,type="task-apt-install"):
    parse_packageslist(aptoption, packagefilelist,action="install",type=type)

def convert_packageslist(aptoption, packagefilelist,type="task-apt-install"):
    convert_file="/tmp/convert"
    with open(convert_file,"w") as f:
        f.write("#!/bin/sh\nset -x\n")
        parse_packageslist(aptoption, packagefilelist,action="convert",type=type,convert_file=f)
    
def verify_packageslist(aptoption, packagefilelist):
    parse_packageslist(aptoption, packagefilelist,action="verify")
    
if __name__ == '__main__':
    install_packageslist("../data/packageslist.txt")
