import os
import json
import argparse
import urllib
from passlib.apps import custom_app_context as pwd_context
from cryptography.fernet import Fernet

class CheckMeIn(object):
    URL_BASE = 'http://tfi.checkmein.site'    
    #URL_BASE = "http://127.0.0.1:8089"

    def __init__(self):
        with open('checkmein.key','rb') as key_file:
            self.key = Fernet(key_file.read())

    def sendRequest(self, requestStr):
        requestStr = self.URL_BASE + requestStr
        print(requestStr)
        try:
            return urllib.request.urlopen(requestStr)
        except AttributeError:
            return urllib.urlopen(requestStr)   

class Users(object):
    def __init__(self):
        self.userfile_mtime = 0
        self.users = {}
        self.path = 'checkmein.json'
        self.loadIfNewer()
        self.checkMeIn = CheckMeIn()
    
    def sendUnlock(self, user):
        self.checkMeIn.sendRequest('/unlock?location=BFF&barcode=' + user['barcode'])

    def getUpdatedAccounts(self):
        encryptedResults = self.checkMeIn.sendRequest('/admin/getKeyholderJSON').read()
        print(encryptedResults)
        # decrypt should happen here
        results = self.checkMeIn.key.decrypt(encryptedResults)

        self.users = json.loads(results)
        with open(self.path, 'w') as user_file:
            json.dump(self.users, user_file)
        self.userfile_mtime = os.stat(self.path).st_mtime
        with open("iptables", 'w') as iptable_file:
            self.make_iptable_file(iptable_file)

    def loadIfNewer(self):
        # If we have the most recent
        if os.stat(self.path).st_mtime == self.userfile_mtime:
            return
        try:
            with open(self.path, 'r') as user_file:
                self.users = json.loads(user_file.read())
            self.userfile_mtime = os.stat(self.path).st_mtime
        except IOError:
            pass

    def get(self, username):   # this will return the user if it finds it
        self.loadIfNewer()
        if not username:
            return ''  # not found
        lower_username = username.lower()
        for user in self.users:
            print(user)
            if user['user'].lower() == lower_username:
                return user
        return None   # not found

    def make_iptable_file(self, f):
        self.loadIfNewer()
        f.write("# Generated by Doorapp\n")
        f.write("*filter\n")
        f.write(":INPUT ACCEPT [0:0]\n")
        f.write(":FORWARD ACCEPT [0:0]\n")

        f.write("# Allow loopback\n")
        f.write("-I INPUT 1 -i lo -j ACCEPT\n")
        f.write("-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT\n")
        
        for u in self.users:
            for d in u['devices']:
                f.write("-A INPUT -m mac --mac-source " + d['mac'] + " -j ACCEPT\n")
        
        f.write("# -A INPUT -j LOG\n")
        f.write("-A INPUT -j ACCEPT\n")
        f.write("COMMIT\n")

    def verify_password(self, username_in, password):
        self.loadIfNewer()
        user = self.get(username_in)
        if user:
            return pwd_context.verify(password, user['password'])
        else:
            return False

if __name__ == '__main__':
     users = Users()
     users.make_iptable_file(open("iptables", "w"))