# Script that process stdout from pcf and creates IRI messages
#
# Copyright (C) 2014 Martin Holkovic
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import inspect

parserMainFilename = "parser_main.py"


# debug funkcia
def lineno():
    return inspect.currentframe().f_back.f_lineno
    
def shell(query):
    stdout = os.popen(query).read()
    return stdout[0:-1]


################################################################################
#### Funkcie na pracovanie s parserom ##########################################
################################################################################

def get_running_port():
    return shell("ps uax | grep " + parserMainFilename + " | grep -v grep | grep -e '[0-9]$' | head --lines=1 | sed 's/^.*\s\([0-9]\+\)$/\\1/'")

def get_running_pid():
    return shell("ps uax | grep " + parserMainFilename + " | grep -v grep | grep -e '[0-9]$' | head --lines=1 | sed 's/^[^ ]\+\s\+\([0-9]\+\)\s.*$/\\1/'")

################################################################################
#### Funkcie na prekonvertovanie dat do inej zobrazovacej podoby ###############
################################################################################

#funkcia na vypocet ciselnej hodnoty zo stringu
def str_to_int(string):
    result = 0
    for char in string: # prejdem kazdy znak zo vstupu
        result = result*256 + ord(char) # vysledok 
    return result

#string prekonvertujem po bajtoch do hexa podoby
def str_to_hex(string):
    hexResult = ""
    for char in string: # prejdem kazdy znak zo vstupu
        hexa = hex(ord(char)).replace('0x', '') # ziskam hexa podobu a odstranim znak "0x"
        if len(hexa) == 1: #kazdy bajt musi mat 2 zobrazene znaky
            hexResult += "0"
        hexResult += hexa
    return hexResult

#hexa string prekonvertujem po bajtoch do bezneho stringu podoby
def hex_to_str(string):
    result = ""
    hexString = string.decode("hex")
    for i in range(0, len(hexString) / 2): # prejdem kazdy znak zo vstupu
        result += chr(int(hexString[i*2:i*2+2], 16))
    return result

#cislo prekonvertujem do hexa podoby !!! funguje len do 16 bitov(2 bajty) z dovodu konstanty 65520 !!!
def int_to_hex(num):
    hexResult = ""
    if num == 0: # specialny pripad
        hexResult = "0"
    while num > 0:
        rest = num % 16
        if rest > 9: #znak A-F
            char = chr(rest + 97 - 10)
        else: # cislice 0-9
            char = chr(rest + 48)
        hexResult = char + hexResult
        num = num & 65520 #vynulujem dolne 4 bity
        num = num / 16 # posuv o 4 bity do prava
    return hexResult


################################################################################
#### Funkcie na prekonvertovanie surovych dat do ludskej podoby ################
################################################################################

#prekonvertuje string do podoby MAC adresy
# MAC adresa musi byt dlha 12 znakov (t.j. zadana bez oddelovacov ":")
def str_to_mac(string):
    string = str_to_hex(string)
    result = ""
    for i in range(0, 12): #prejde postupne 12 znakov
        result += string[i]
        if i%2 == 1 and i != 11: #medzi pary bajtov vlozi ":"
            result += ":"
    return result

#prekonvertuje string do podoby IPv4 adresy
# IPv4 adresa musi byt zadana v podobe 4 bajtov
def str_to_ip4(string):
    ip = ""
    for i in range(0,4): # prejde postupne 4 bajty
        ip += str(str_to_int(string[i:i+1])) #bajt prevedie na cislo a vytvori z neho string
        if i != 3: # medzi jednotlive casti sa vlozi oddelovac "."
            ip += "."
    return ip

#prekonvertuje string do IPv6 podoby
def str_to_ip6(string):
    ip = ""
    for i in range(0,len(string),2): # medzi kazde 2 bloky vlozim oddelovac ":"
        if i != 0:
            ip += ":"
        num = str_to_int(string[i:i+2])
        ip += int_to_hex(num)
    # v adrese nahradim najvacsi vyskyt :0:0: za ::
    for i in range(7, 1, -1):
        # vytvorim si string znakov :0:0:0:, ktory neskor vyhladavam v texte
        search = ""
        for j in range(0, i):
            search += ":0"
        
        if search + ":" in ip: # :0:0: ma vacsiu prioritu ako :0:0
            ip = ip.replace(search + ":", "::", 1) # postupnost :0:0:0: nahradim :: ale max 1x
            return ip #aby sa nenahradzovalo viac ako 1x
        if search in ip:
            ip = ip.replace(search, "::", 1) # postupnost :0:0:0 nahradim :: ale max 1x
            if ip == "0::":
                return "::"
            return ip #aby sa nenahradzovalo viac ako 1x
    return ip


# funkcia vrati z interface identifier lokalnu IPv6 adresu
def ipv6ip_from_interface_identifier(string):
    ip = ""
    for i in range(0,len(string),2):
        if i != 0: # medzi bloky IPv6 adresy vlozim oddelovac ":"
            ip += ":"
        num = str_to_int(string[i:i+2])
        ip += int_to_hex(num) # pridanie do stringu
    ip = "fe80::"+ip
    return ip

