import re
import os
import sys
import pandas as pd

from _p_columns import columns, port_index, src_index, net_index

df = pd.DataFrame(columns=columns)

def convert_to_uppercase(input_string):
    return input_string.upper()

# Look up a port number assigned to a constant in another file
def find_port_number(filename, search_string):
    found_port = None
    with open(filename, 'r') as file:
        for line in file:
            match = re.search(rf'{search_string}\s*=\s*(\d+)', line)
            if match:
                found_port = int(match.group(1))
                break
    return found_port

def remove_prefix(input_string):
    # Find the index of the first period
    period_index = input_string.find('.')
    
    if period_index != -1:
        return input_string[period_index + 1:]
    else:
        # Return the original string
        return input_string

def delete_file(file_path):
    try:
        # Check if the file exists
        if os.path.exists(file_path):
            # Delete the file
            os.remove(file_path)
            print(f"File '{file_path}' deleted successfully.")
        else:
            print(f"File '{file_path}' does not exist.")
    except Exception as e:
        print(f"An error occurred: {e}")

def is_numeric(array, index):
    array = [element.strip() for element in array]
    # Check if the array has an integer at the element to be tested
    if len(array) > index:
        return array[index].isnumeric()
    else:
        return False

def prepend_string(main_string, prepend_string):
    return prepend_string + main_string

def append_string(*args, **kwargs):
    return prepend_string(*args, **kwargs)

def extract_docu_comments(input_file, out_file):
    sect = "N/A"
    prot = "N/A"
    with open(input_file, 'r') as file:
        lines = file.readlines()

    for line in lines:

        match = re.search(r'^(\S+)\s*=\s*(\{|\\)', line)
        if match:
            sect = match.group(1).strip()
            sect = append_string(',', sect)
            prot = "N/A, "
        match = re.search(r'("tcp":|"udp":)', line)
        if match:
            prot = match.group(1).strip()
            prot = prot.replace(':', '').strip()
            prot = convert_to_uppercase(prot)
            prot = append_string(',', prot)

        # Check if the line contains a comment starting with 'docu' followed by
        # a colon
        if '#' in line and 'docu:' in line.lstrip():
            docu_line = re.sub(r',?\s*#\s*(noqa: E501)?\s+docu:\s*', ',', line).strip()
            docu_line = docu_line.replace(':', ',').strip()
            docu_line = prepend_string(docu_line, prot)
            docu_line = prepend_string(docu_line, sect)
            docu_line = docu_line.replace('"', '').strip()
            column_values = docu_line.split(',')

            if not is_numeric(column_values, port_index):
                const =  column_values[port_index]
                column_values[port_index] = find_port_number(const_file, remove_prefix(column_values[port_index]))
                print("Replaced " + const.strip() + " with " + str(column_values[port_index]))

            if 'OAM' in column_values[src_index]:
                column_values[net_index] = 'oam'
 
            # print("Processing: " + line)
            df.loc[len(df)] = column_values

    ports_column_name = df.columns[port_index]
    df[ports_column_name] = pd.to_numeric(df[ports_column_name], errors='coerce')
    df.to_excel(excel_file, index=False)
    
    print(f"Ports list successfully extracted to '{excel_file}'.")

if len(sys.argv) != 4:
    print(f"""\
This script reads a python file to create an Excel sheet of firewall
port definitions.

Usage:  {os.path.basename(__file__)} <ports_file> <constants_file> <excel_file>
Example: python ./py_2_xlsx.py platform_firewall.py constants.py FW_PORTS.xlsx
""")
    sys.exit(1)


input_file = str(sys.argv[1])
const_file = str(sys.argv[2])
excel_file = str(sys.argv[3])

# Extract lines with docu comments
extract_docu_comments(input_file, excel_file)