#!python

import qrcode
import http.server
import socketserver
import random
import os
import socket
import sys
from shutil import make_archive, rmtree, copy2
import pathlib
import signal
import platform


MacOS = "Darwin"
Linux = "Linux"
Windows = "Windows"
operating_system = platform.system()


def get_ssid():

    if operating_system == MacOS:
        ssid = os.popen("/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | awk '/ SSID/ {print substr($0, index($0, $2))}'").read().strip()
        return ssid
    
    elif operating_system == "Linux":
       ssid = os.popen("iwgetid -r").read().strip()
       return ssid

    else:
        # List interface information and extract the SSID from Profile
        # note that if WiFi is not connected, Profile line will not be found and nothing will be returned.
        interface_info = os.popen("netsh wlan show interfaces").read()
        for line in interface_info.splitlines():
            if line.strip().startswith("Profile"):
                ssid = line.split(':')[1].strip()
                return ssid


def get_local_ip():
    try: 
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        return s.getsockname()[0]
    except OSError:
        print("Network is unreachable")
        sys.exit()


def random_port():
    return random.randint(1024, 65535)


def start_server(fname, cwd):
    PORT = random_port()
    LOCAL_IP = get_local_ip()
    SSID = get_ssid()

    # Using .tmpqr since .tmp is very common
    #create the .tmp_qr folder in /tmp file of unix system 
    TEMP_DIR_NAME = "/tmp/.tmp_qr" 

    # Variable to mark zip for deletion, if the user uses a folder as an argument
    delete_zip = 0

    # Checking if given fname is a path
    if fname.startswith("/"):
        os.chdir("/")

    # Checking if given file name or path is a directory
    if os.path.isdir(fname):
        zip_name = pathlib.PurePosixPath(fname).name

        try:
            # Zips the directory
            path_to_zip = make_archive(zip_name, "zip", fname)
            fname = path_to_zip.replace(os.getcwd(), "")
            # The above line replacement leaves a / infront of the file name
            fname = fname.replace("/", "")
            delete_zip = fname
        except PermissionError:
            print("Permission denied")
            sys.exit()

    # Makes a directory name .tmp_qr and stores the file there
    try:
        os.makedirs(TEMP_DIR_NAME)
    except:
        print("Directory already exist") # preventing directory already exist crash..

    try:
        # Move the file to .tmpqr
        copy2(fname, TEMP_DIR_NAME)
    except FileNotFoundError:
        print("No such file or directory")
        rmtree(TEMP_DIR_NAME)
        sys.exit()

    # Change our directory to .tmpqr
    os.chdir(TEMP_DIR_NAME)

    handler = http.server.SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(("", PORT), handler)
    
    # Tweaking fname to make a perfect url
    fname = fname.split('/')
    fname = fname[-1]
    fname = fname.replace(" ", "%20")

    # This is the url to be encoded into the QR code
    address = "http://" + str(LOCAL_IP) + ":" + str(PORT) + "/" + fname

    print("Scan the following QR to start downloading.\nMake sure that your smartphone is connected to \033[1;94m{}\033[0m".format(SSID))
    print_qr_code(address)

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        os.chdir("..")
        rmtree(TEMP_DIR_NAME)

    # If the user sent a directory, a zip was created and then copied to the 
    # temporary directory, this deletes the first created zip
    if delete_zip != 0:

        # Goes back to the dir where the qr-filetransfer was ran
        # to delete the zip
        os.chdir(cwd)
        os.remove(delete_zip)
    # Just being nice not messing up your bash prompt :)
    print("")
    
    sys.exit()

def print_qr_code(address):
    qr = qrcode.QRCode(version=1,
                error_correction=qrcode.constants.ERROR_CORRECT_L,
                box_size=10,
                border=4,)
    qr.add_data(address)
    qr.make()

    if operating_system != Windows:
        # According to gomercin on GitHub, print_tty
        # prints out gibberish.
        # print_tty() shows a better looking QR code.
        # So thats why I am using print__tty() instead
        # of print_ascii() for all operating systems
        qr.print_tty()

    else:
        qr.print_ascii()


def main():
    if operating_system != Windows:
        # SIGSTP does not work in Windows
        # This disables CTRL+Z while the script is running
        signal.signal(signal.SIGTSTP, signal.SIG_IGN)
    
    # So that we can come back to this dir 
    CURRENT_DIR = os.getcwd()

    # If no argument is given or invalid agrument then it shows help
    if len(sys.argv) == 1 or sys.argv[1] in ["-h", "--help"]:
        print("usage: qr-filetransfer.py [-h] FILE")
        sys.exit()

    if sys.argv[1]:
        start_server(fname=sys.argv[1], cwd=CURRENT_DIR)

if __name__=="__main__":
	main()
