from sema.common import get
import os
import lxml.etree as ET

def create_setting_file(path):
    """Returns 200: Successful,
       701: Selected file is a .setting file
       702: Selected file is a .setting.xml file"""

    if os.path.isfile(path + '.setting'):
        return 701

    if os.path.isfile(path + '.setting.xml'):
        return 702

    try:
        root = ET.Element("root")
        
        tree = ET.ElementTree(root)
        tree.write(path + '.setting.xml', xml_declaration=True, pretty_print=True)

        file = open(path + '.setting', 'w')

        file.write('#This is a setting maker file\n#This file is autogenerated!\n#Please use provided tools for editing and be cautious when editing it manually!\n')

        file.close()

        return 200

    except Exception as e:

        try:
            os.remove(path + '.setting.xml')
        except OSError:
            pass

        try:
            os.remove(path + '.setting')
        except OSError:
            pass

        return e


def add_option_to_file(path_to_dot_setting, name, comment):
    """Returns 200: Successful,
       201: Definition for option already exists in setting.xml file"""

    file = open(path_to_dot_setting, 'a')

    file.write('#' + comment + '\n' + name + ':\n')

    file.close()

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()
                      
    if root.find("option[@name='" + name.lower() + "']") == None:
        element = ET.Element("option", name=name.lower())
        element.text = comment
        root.append(element)
        
        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200
    else:
        return 201
        

def remove_option_from_file(path_to_dot_setting, name):
    """Returns 200: Successful,
       201: Option removed successfully but Option didn't exist in setting.xml file
            It causes no problem in removing but means that .setting.xml was corrupted."""
    file_r = open(path_to_dot_setting, 'r')
    file_temp = open(path_to_dot_setting + '.temp', 'w')

    file_r_contents = file_r.readlines()

    skip = False

    for i in range(len(file_r_contents)):
        if skip == True:
            skip = False
            continue
        elif file_r_contents[i][0] == ' ' or file_r_contents[i][0] == '\n':
            pass
        elif file_r_contents[i][0] == '#' and file_r_contents[i+1][0] != '#':
            if name.upper().strip() == file_r_contents[i+1][:file_r_contents[i+1].find(':')].upper().strip():
                skip = True
            else:
                file_temp.write(file_r_contents[i])
        else:
            file_temp.write(file_r_contents[i])

    file_r.close()
    file_temp.close()

    os.remove(path_to_dot_setting)
    os.rename(path_to_dot_setting + '.temp', path_to_dot_setting)

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()
    
    element = root.find("option[@name='" + name.lower().strip() + "']")

    if element != None:
        root.remove(element)

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200
        
    else:
        return 201


def change_option_name(path_to_dot_setting, current_name, new_name):
    """Returns 200: Successful,
       201: Option name was not found in .setting.xml file, file could be corrupted"""
    file_r = open(path_to_dot_setting, 'r')
    file_temp = open(path_to_dot_setting + '.temp', 'w')

    for line in file_r.readlines():
        if line[0] == ' ' or line[0] == '\n':
            pass
        elif current_name.upper().strip() == line[:line.find(':')].upper().strip() and line[0] != '#':
            file_temp.write(new_name.strip() + line[line.find(':'):])
        else:
            file_temp.write(line)

    file_r.close()
    file_temp.close()

    os.remove(path_to_dot_setting)
    os.rename(path_to_dot_setting + '.temp', path_to_dot_setting)

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()
    
    element = root.find("option[@name='" + new_name.lower().strip() + "']")

    if element != None:
        root.remove(element)

    element = root.find("option[@name='" + current_name.lower().strip() + "']")

    if element == None:#This can only happen if .xml file is altered manually

        file_r = open(path_to_dot_setting, 'r')

        file_r_contents = file_r.readlines()
        
        comment = ''

        for i in range(len(file_r_contents)):
            if file_r_contents[i][0] == '#' and file_r_contents[i+1][0] != '#':
                if new_name.upper().strip() == file_r_contents[i+1][:file_r_contents[i+1].find(':')].upper().strip():
                    comment = file_r_contents[i][1:].replace('\n', '')
                    break

        file_r.close()

        element = ET.Element("option", name=new_name.lower().strip())
        element.text = comment
        root.append(element)

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 201
    
    else:

        element.attrib['name'] = new_name.lower()

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200


def add_simple_value(path_to_dot_setting, option_name, value, comment):
    """Returns 200: Successful,
       700: Option not found in .xml file"""
    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700
    
    else:

        sub_element = ET.Element("value", name=value.lower().strip())
        sub_element.text = comment

        element.append(sub_element)

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200


def add_range_value(path_to_dot_setting, option_name, min, max, step, comment):
    """Returns 200: Successful,
       700: Option not found in .xml file
       701: Min is not a number
       702: Max is not a number
       703: step is not a number
       704: all are empty"""

    if min == max == step == '':
        return 704

    if min != '':
        try:
            float(min)
        except:
            return 701
    
    if max != '':
        try:
            float(max)
        except:
            return 702

    if step != '':
        try:
            float(step)
        except:
            return 703

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700
    
    else:

        sub_element = ET.Element("range")
        sub_element.attrib['min'] = min
        sub_element.attrib['max'] = max
        sub_element.attrib['step'] = step
        sub_element.text = comment

        element.append(sub_element)

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200


def remove_possible_value_by_number(path_to_dot_setting, option_name, number_from_zero):
    """Removes a value from an option by it's position in .xml file
       Return: 200 on success
               700 on option not found
               701 number don't exist"""

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700

    if number_from_zero < 0:
        return 701

    if len(element.getchildren()) >= number_from_zero+1:
       
        element.remove(element.getchildren()[number_from_zero])

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)
        
        return 200

    else:
        return 701


def set_value_comment_by_number(path_to_dot_setting, option_name, number_from_zero, comment):
    """Sets a comment for a value in option by it's position in .xml file
       Return: 200 on success
               700 on option not found
               701 number don't exist"""

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700

    if number_from_zero < 0:
        return 701

    if len(element.getchildren()) >= number_from_zero+1:
        
        element.getchildren()[number_from_zero].text = comment

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200
        
    else:
        return 701


def set_simple_possible_value_by_number(path_to_dot_setting, option_name, number_from_zero, new_name):
    """Sets name for a simple value in option by it's position in .xml file
       Return: 200 on success
               700 on option not found
               701 number don't exist"""

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700

    if number_from_zero < 0:
        return 701

    if len(element.getchildren()) >= number_from_zero+1:
        
        element.getchildren()[number_from_zero].attrib['name'] = new_name

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200
        
    else:
        return 701


def set_ranged_possible_value_by_number(path_to_dot_setting, option_name, number_from_zero, min, max, step):
    """Sets values for a ranged value in option by it's position in .xml file
       Return: 200 on success
               700 on option not found
               701 number don't exist
               703 Can't have 3 empty values"""


    if min == max == step == '':
        return 703

    parser = ET.XMLParser(remove_blank_text=True)

    tree = ET.parse(path_to_dot_setting + '.xml', parser)

    root = tree.getroot()

    element = root.find("option[@name='" + option_name.lower().strip() + "']")

    if element == None:
        return 700

    if number_from_zero < 0:
        return 701

    if len(element.getchildren()) >= number_from_zero + 1:
        
        range_element = element.getchildren()[number_from_zero]
       
        range_element.attrib['min'] = min
        range_element.attrib['max'] = max
        range_element.attrib['step'] = step

        tree.write(path_to_dot_setting + '.xml', xml_declaration=True, pretty_print=True)

        return 200
        
    else:
        return 701

