#!/usr/bin/python3
import json
import netaddr
import gzip
import re
import os
import sys
import pprint
import requests
MAC_URL = 'http://macvendors.co/api/%s'

def getHardwareModelFromEntry(d):
    hardware_model = "UNKNOWN"
    if d != None:
        if "hardware" in d:
            if "model" in d["hardware"]:
                hardware_model = d["hardware"]["model"]
    return hardware_model

def ipv62mac(ipv6):
    # remove subnet info if given
    subnetIndex = ipv6.find("/")
    if subnetIndex != -1:
        ipv6 = ipv6[:subnetIndex]

    ipv6Parts = ipv6.split(":")
    macParts = []
    for ipv6Part in ipv6Parts[-4:]:
        while len(ipv6Part) < 4:
            ipv6Part = "0" + ipv6Part
        macParts.append(ipv6Part[:2])
        macParts.append(ipv6Part[-2:])

    # modify parts to match MAC value
    macParts[0] = "%02x" % (int(macParts[0], 16) ^ 2)
    del macParts[4]
    del macParts[3]

    return ":".join(macParts)

class LogRecord:
    def __init__(self,record):
        record = record.replace("%2B","+")
        regex = r'(fd21.*) - - \[(.*) "GET /gluon/(.*)/sysupgrade/gluon-ffs-([0-9]\.[0-9]\+[0-9]+-[0-9]+-[0-9]+-g\.[0-9a-z]+-s\.[0-9a-z]+)-(.*)\ HTTP/1.1" ([0-9]+) [0-9]+ "-" "(.*)"'
        result = re.search(regex,record)
        try:
            groups = result.groups()
        except:
            print(record)
            print("error parsing record")
            sys.exit(1)
        self.ipv6 = groups[0]
        self.date = groups[1]
        self.branch = groups[2]
        self.release = groups[3]
        self.model = groups[4]
        self.status = groups[5]
        self.agent = groups[6]
        self.segment = int(self.ipv6.split(":")[2][2:])

try:
    allFirmwareDownloads = json.load(open("firmwareDownloads.json","r"))
except:
    allFirmwareDownloads = []

access = ""

try:
    #for i in range(2,15):
    #   access += gzip.open("/var/log/nginx/access.log.%i.gz"%(i),"rt").read()
    access += open("/var/log/nginx/access.log.1").read()
    access += open("/var/log/nginx/access.log").read()

except:
    print("not using /var/log/nginx/access.log")
try:
    access += open("access.log").read()
except:
    pass

allDownloads = access.strip().split("\n")
allNewFirmwareDownloads = [l for l in allDownloads if l.startswith("fd21:") and "sysupgrade" in l and "manifest" not in l]

for f in allNewFirmwareDownloads:
    if f not in allFirmwareDownloads:
        allFirmwareDownloads.append(f)

json.dump(allFirmwareDownloads,open("firmwareDownloads.json","w"),sort_keys=True, indent=4, separators=(',', ': '))


nodesdbFilename = "/home/www/html/netinfo/json/nodesdb.json"
if not os.path.isfile(nodesdbFilename):
    nodesdbFilename = "nodesdb.json"
data = json.load(open(nodesdbFilename))

for download in allFirmwareDownloads:
    r = LogRecord(download)
    mac = ipv62mac(r.ipv6)

    if mac in data:
        d = data[mac]
        currentRelease = d["software"]["firmware"]["release"]
        status = d["status"]
        hostname = d["hostname"]
        hardware_model = getHardwareModelFromEntry(d)
        if currentRelease < r.release:
            print("%s (%s) %s -> %s Segment %i %s status %s @ %s" % (mac, hostname, currentRelease, r.release, r.segment, hardware_model, status, r.date))
    else:
        #request = requests.get(MAC_URL % mac)
        #pprint.pprint(request.json())
        print("%s %s with agent %s seems not to be a node @ %s"%(r.ipv6,mac,r.agent,r.date))