#!/usr/bin/python

import csv
import xml.etree.ElementTree as ET
import os
import sys
import shutil


# #########################################################
# Represents all the metadata classes for import
# #########################################################
class RecordInfo:
    """Holds record info information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'recordInfo')

        if self.value:
            top_level.text = self.value.strip()

        return top_level


class RecordContentSource:
    """Holds content source information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'recordContentSource')

        if self.value:
            top_level.text = self.value.strip()

        return top_level


class LanguageOfCataloging:
    """Holds language of cataloging information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'languageOfCataloging')

        if self.value:
            top_level.text = self.value.strip()

        return top_level


class PhysicalDescription:
    """Holds physical description information"""

    def __init__(self):
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'physicalDescription')

        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class TypeOfResource:
    """Holds type of resource information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'typeOfResource')
        top_level.text = self.value.strip()

        return top_level


class Form:
    """Holds form information"""

    def __init__(self):
        self.authority = ''
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'form')

        if self.authority:
            top_level.set('authority', self.authority.strip())

        top_level.text = self.value.strip()
        return top_level


class InternetMediaType:
    """Holds internet media type information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'internetMediaType')

        top_level.text = self.value.strip()
        return top_level


class DigitalOrigin:
    """Holds digital origin information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'digitalOrigin')

        top_level.text = self.value.strip()
        return top_level


class Extent:
    """Holds extent information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'extent')

        top_level.text = self.value.strip()
        return top_level


class Abstract:
    """Holds abstract information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'abstract')

        top_level.text = self.value.strip()

        return top_level


class Subject:
    """Holds subject information"""

    def __init__(self):
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'subject')

        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class Topic:
    """Holds topic information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'topic')
        top_level.text = self.value.strip()
        return top_level


class Geographic:
    """Holds geographic information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'geographic')
        top_level.text = self.value.strip()
        return top_level


class Genre:
    """Holds genre information"""

    def __init__(self):
        self.authority = ''
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'genre')

        if self.authority:
            top_level.set('authority', self.authority.strip())

        top_level.text = self.value.strip()
        return top_level


class Note:
    """Holds note information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'note')

        top_level.text = self.value.strip()
        return top_level


class Role:
    """Holds role information"""

    def __init__(self):
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'role')

        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class Language:
    """Holds language information"""

    def __init__(self):
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'language')

        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class LanguageTerm:
    """Holds language term information"""

    def __init__(self):
        self.type = ''
        self.value = ''
        self.authority = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'languageTerm')

        if self.type:
            top_level.set('type', self.type.strip())

        if self.authority:
            top_level.set('authority', self.authority.strip())

        top_level.text = self.value.strip()
        return top_level


class RoleTerm:
    """Holds role term information"""

    def __init__(self):
        self.value = ''
        self.authority = ''
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'roleTerm')

        if self.type:
            top_level.set('type', self.type.strip())

        if self.authority:
            top_level.set('authority', self.authority.strip())

        top_level.text = self.value.strip()
        return top_level


class Name:
    """Holds name information"""

    def __init__(self):
        self.type = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'name')

        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class NamePart:
    """Holds name part information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'namePart')

        top_level.text = self.value.strip()

        return top_level


class DateCreated:
    """Holds date created information"""

    def __init__(self):
        self.value = ''
        self.encoding = ''
        self.qualifier = ''
        self.keyDate = ''
        self.point = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'dateCreated')

        if self.encoding:
            top_level.set('encoding', self.encoding.strip())

        if self.qualifier:
            top_level.set('qualifier', self.qualifier.strip())

        if self.keyDate:
            top_level.set('keyDate', self.keyDate.strip())

        if self.point:
            top_level.set('point', self.point.strip())

        top_level.text = self.value.strip()

        return top_level


class DateIssued:
    """Holds date issued information"""

    def __init__(self):
        self.value = ''
        self.encoding = ''
        self.qualifier = ''
        self.keyDate = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'dateIssued')

        if self.encoding:
            top_level.set('encoding', self.encoding.strip())

        if self.qualifier:
            top_level.set('qualifier', self.qualifier.strip())

        if self.keyDate:
            top_level.set('keyDate', self.keyDate.strip())

        top_level.text = self.value.strip()

        return top_level


class OriginInfo:
    """Holds origin info information"""

    def __init__(self):
        self.value = ''

    @staticmethod
    def to_mods_element(parent_element):
        top_level = ET.SubElement(parent_element, 'originInfo')
        return top_level


class Place:
    """Holds place information"""

    def __init__(self):
        self.value = ''

    @staticmethod
    def to_mods_element(parent_element):
        top_level = ET.SubElement(parent_element, 'place')
        return top_level


class PlaceTerm:
    """Holds place term information"""

    def __init__(self):
        self.type = ''
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'placeTerm')

        if self.type:
            top_level.set('type', self.type.strip())

        top_level.text = self.value.strip()

        return top_level


class RelatedItem:
    """Holds Releated Item information"""

    def __init__(self):
        self.type = ''
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'relatedItem')
        if self.type:
            top_level.set('type', self.type.strip())

        return top_level


class TitleInfo:
    """Holds identifier information"""

    def __init__(self):
        self.value = ''

    @staticmethod
    def to_mods_element(parent_element):
        top_level = ET.SubElement(parent_element, 'titleInfo')
        return top_level


class Title:
    """Holds title information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'title')
        top_level.text = self.value.strip()
        return top_level


class Location:
    """Holds identifier information"""

    def __init__(self):
        self.value = ''

    @staticmethod
    def to_mods_element(parent_element):
        top_level = ET.SubElement(parent_element, 'location')
        return top_level


class PhysicalLocation:
    """Holds physical location information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'physicalLocation')
        top_level.text = self.value.strip()
        return top_level


class ShelfLocator:
    """Holds shelf locator information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'shelfLocator')
        top_level.text = self.value.strip()
        return top_level


class AccessCondition:
    """Holds access condition information"""

    def __init__(self):
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'accessCondition')
        top_level.text = self.value.strip()
        return top_level


class Identifier:
    """Holds identifier information"""

    def __init__(self):
        self.type = ''
        self.value = ''

    def to_mods_element(self, parent_element):
        top_level = ET.SubElement(parent_element, 'identifier')
        if self.type:
            top_level.set('type', self.type.strip())

        top_level.text = self.value.strip()
        return top_level


#
# Build the xml file using the above classes
#
def build_xml(row):
    print('build xml')
    root = ET.Element('mods', {"xmlns:xlink": "http://www.w3.org/1999/xlink",
                               "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
                               "xmlns": "http://www.loc.gov/mods/v3",
                               "version": "3.5",
                               "xsi:schemaLocation": "http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-5.xsd"})

    location_element = None
    if row[0]:
        job_number = Identifier()
        job_number.type = 'job'
        job_number.value = row[0]
        job_number.to_mods_element(root)

    # physical location information
    if row[1]:
        location = Location()
        location_element = location.to_mods_element(root)

        physical_location = PhysicalLocation()
        physical_location.value = row[1]
        physical_location.to_mods_element(location_element)

    # shelf location information
    if row[2]:
        shelf_locator = ShelfLocator()
        shelf_locator.value = row[2]
        shelf_locator.to_mods_element(location_element)

    # title information
    if row[3]:
        title_info = TitleInfo()
        title_info_element = title_info.to_mods_element(root)

        title = Title()
        title.value = row[3]

        title.to_mods_element(title_info_element)

    # related item information
    if row[4]:
        related_item = RelatedItem()
        related_item.type = 'host'
        related_item_element = related_item.to_mods_element(root)

        title_info2 = TitleInfo()
        title_info_element2 = title_info2.to_mods_element(related_item_element)
        title2 = Title()
        title2.value = row[4]

        title2.to_mods_element(title_info_element2)

    # date created information
    if row[5]:
        origin_info_element = OriginInfo().to_mods_element(root)
        date_created = DateCreated()
        date_created.value = row[5]
        date_created.encoding = "w3cdtf"
        date_created.keyDate = "yes"
        date_created.to_mods_element(origin_info_element)

        # add date issued so it shows up in dublin core
        date_issued = DateIssued()
        date_issued.value = row[5]
        date_issued.encoding = "w3cdtf"
        date_issued.keyDate = "yes"
        date_issued.to_mods_element(origin_info_element)

    # date approximate
    if row[6]:
        date_approx_info_element = OriginInfo().to_mods_element(root)
        date_approximate = DateCreated()
        date_approximate.value = row[6]
        date_approximate.encoding = "w3cdtf"
        date_approximate.qualifier = "approximate"
        date_approximate.to_mods_element(date_approx_info_element)

    # date inferred
    if row[7]:
        date_inferred_info_element = OriginInfo().to_mods_element(root)
        date_inferred = DateCreated()
        date_inferred.value = row[7]
        date_inferred.encoding = "w3cdtf"
        date_inferred.qualifier = "inferred"
        date_inferred.to_mods_element(date_inferred_info_element)

    # date questionable
    if row[8]:
        date_questionable_info_element = OriginInfo().to_mods_element(root)
        date_questionable = DateCreated()
        date_questionable.value = row[8]
        date_questionable.encoding = "w3cdtf"
        date_questionable.qualifier = "questionable"

        date_questionable.to_mods_element(date_questionable_info_element)

    # begin date
    if row[9]:
        begin_date_info_element = OriginInfo().to_mods_element(root)
        date_begin = DateCreated()
        date_begin.value = row[9]
        date_begin.encoding = "marc"
        date_begin.point = "start"

        date_begin.to_mods_element(begin_date_info_element)

    # end date
    if row[10]:
        end_date_info_element = OriginInfo().to_mods_element(root)
        end_begin = DateCreated()