class NodeHandler():
    '''
    Description:
    The NodeHandler class is intended for generating and maintaining large numbers of Jenkins
    nodes from a csv file.

    Note:
    Need a method to compare current csv with existing nodes and do: Create / Updated / Delete accordingly
    Need means for auto launch jenkins node on slave host (server) after (device) nodes are created

    '''

    def __init__(self):
        self.host = ''
        self.username = ''
        self.password = ''
        self.jenkins_node_config = 'config.xml'

        self.set_args()
        self.jenkins = Jenkins(self.host_url, self.username, self.password)
        self.elements = []
        self.get_csv(self.node_list)

        if self.delete_all:
            for device in self.elements[1:]:
                self.delete(device)
        else:
            for device in self.elements[1:]:
                self.create(device)


    def set_args(self):
        parser = argparse.ArgumentParser(description='Script to manage Jenkins nodes')

        parser.add_argument('-s','--server', help="Enter server", required=True)
        parser.add_argument('-u','--username', help="Enter username", required=True)
        parser.add_argument('-p','--password', help="Enter password", required=True)

        parser.add_argument('-n','--node-list', help="Specify CSV file of nodes to be created/updated in bulk", default='devices.csv', required=False)
        parser.add_argument('-d','--delete-all', help="Flag all nodes in list for deletion", action='store_true', required=False)
        parser.add_argument('-c','--credentials-id', help="Enter CredentialsId (required for Web QA Jenkins)", default='xxxxxxxxx', required=False)

        args = vars(parser.parse_args())

        # set any input values
        self.username = args['username']
        self.password = args['password']
        self.host = args['server']
        self.host_url = 'http://{}/'.format(self.host)
        self.node_list = args['node_list']
        self.delete_all = args['delete_all']
        self.credentials_id = args['credentials_id']


    def demo(self, name_job):
        print self.jenkins.version
        print self.jenkins.keys() # self.jenkinsenkins objects appear to be dict-like, mapping keys (job-names) to
        print self.jenkins[name_job]
        # print self.jenkins[name_job].get_last_good_build()

    def create(self, device):
        (dev_name, description, labels, node_host, port, dev_serial ) = device

        node_exists = self.jenkins.has_node(dev_name)
        if (node_exists):
            print 'Node: ' + dev_name + ' already exists.'
            node_status = 'existing'
        else:
            self.jenkins.create_node(
                name=dev_name,
                num_executors=1,
                node_description=description,
                remote_fs='/TBD',
                labels=labels,
                exclusive=False
            )
            node_status = 'new'
            print 'Creating new node: ' + dev_name


        print 'Updating {} node '.format(node_status)
        self.post_config(device, self.jenkins_node_config)

    def delete(self, device):
        (dev_name, description, labels, node_host, port, dev_serial ) = device

        node_exists = self.jenkins.has_node(dev_name)
        if (node_exists):
            print 'Deleting node: ' + dev_name
            self.jenkins.delete_node(dev_name)
        else:
            print 'Node: {} does not exist.'.format(dev_name)

    def get_csv(self, filename):
        with open(filename) as f:
            data=[tuple(line) for line in csv.reader(f)]
        self.set_elements(data)

    def set_elements(self, elements):
        self.elements = elements

    def pretty_print(self, xml_string):
        root = etree.fromstring( xml_string )
        return etree.tostring(root, pretty_print=True)

    def hydrate_template(self, jenkins_node_config, device):
        (dev_name, description, labels, node_host, port, dev_serial ) = device
        testvars = "b2g-" + dev_name + ".json"

        with open("config_JENKINS_WEB_QA.xml", "r") as file_template:
            xml_config = file_template.read()

        template = Template(xml_config)
        xml_config = template.substitute(dev_name=dev_name,
                                  description=description,
                                  labels=labels,
                                  node_host=node_host,
                                  port=port,
                                  dev_serial=dev_serial,
                                  testvars=testvars,
                                  credentials_id=self.credentials_id)

        try:
            fh = open(self.jenkins_node_config, "w")
            fh.write(xml_config)
        except IOError:
            print "Error: can\'t find file or read data"
        else:
            print "Jenkins node config.xml file created successfully"
        fh.close()
        print '-------------------------------------------'
        print xml_config
        print '-------------------------------------------'


    def get_url(self, device):
        (dev_name, description, labels, node_host, port, dev_serial ) = device
        url = 'http://' + \
              self.username + ':' + self.password + '@' + \
              self.host + '/computer/' + dev_name + '/' + self.jenkins_node_config
        url = 'http://' + self.host + '/computer/' + dev_name + '/' + self.jenkins_node_config
        return url


    def post_config(self, device, xml_filename):
        url = self.get_url(device)

        self.hydrate_template(xml_filename, device)
        print url

        headers = {'crumb':'c2eebfe9791555eb033019384dd261ee','crumbRequestField':'.crumb'}
        r = requests.post(url, data=open(xml_filename, 'rb'), headers=headers)
        print '---------------------------'
        print 'headers'
        print '---------------------------'
        print r.headers
        print '---------------------------'
        print(r.text)