#!/usr/bin/python

import requests as r
import sys
from optparse import OptionParser
import os
import tarfile

'''
DowGo! by NDRAEY 

Structure:

    (root)
        lists
        packages/
            testpackage/
                version
                package-1.0.tar
            testpackage2/
                version
                package-1.0.tar

"lists" structure:
    FILE
    FILE2
    FILE3
'''

class DowErr:
    DOWNOLISTS = 1
    DOWNOPACKAGE = 2
    DOWNOPACKVER = 3
    DOWNOVER = 4
    DOWOTHERERROR = 99

class DowGo:
    def __init__(self):
        self.session = r.Session()
        self.mainurl = "http://c91451dc.beget.tech/dowgo"
        self.hdr = {'User-Agent':'Mozilla/5.0 (DowGo/1.0; Charmeleon; NDRAEY;)'}

    def parselists(self,lists):
        self.lists = self.lists.split("\n")
        return self.lists

    def getlists(self):
        data = self.session.get(self.mainurl+"/lists",
                         headers=self.hdr)
        if (data.status_code>=200 and data.status_code<400):
            self.lists = data.text
            self.lists = self.parselists(self.lists)
            return self.lists
        self.lists=[]
        return DowErr.DOWNOLISTS

    def getlatest(self,name):
        ver = self.session.get(self.mainurl+"/packages/"+name+"/version",
                               headers=self.hdr)
        if (ver.status_code>=200 and ver.status_code<400):
            return ver.text
        else:
            print("Returning NOVER: %s"%ver.text)
            return DowErr.DOWNOVER

    def checkver(self,name,ver):
        dt = self.session.get(self.mainurl+"/packages/"+name+"/package-"+ver+".tar",
                              headers=self.hdr,
                              stream=True)
        if not (dt.status_code>=200 and dt.status_code<400): return DowErr.DOWNOVER
        else: return dt.text

    def torsize(self,size: int):
        r = size
        suff = ""
        if r>1024:
            r/=1024; suff="KB"
        if r>1024:
            r/=1024; suff="MB"
        return ("%.1f"%r)+suff

    def progresstick(self,pkname,cur,size):
        pl = pkname
        if len(pl)>20: pl=pl[0:20]+"..."
        pr = (cur/size)*100
        kstr = ("#"*round(pr/100*30))+(" "*(30-round((pr/100*30))))
        nsiz = self.torsize(int(size))
        print(f"{pl} [{kstr}] {str(pr).split('.')[0]+'%'} of {nsiz}",
              end='\033[K\r',flush=True)

    def downloadpk(self,name,ver,path):
        pk = self.session.get(self.mainurl+"/packages/"+name+"/package-"+ver+".tar",
                              headers=self.hdr,stream=True)
        path = f"{path}/{name}-{ver}.tar"
        with open(path, 'wb') as f:
            for chunk in pk.iter_content(chunk_size=32768):
                self.progresstick(path,f.tell(),int(pk.headers["Content-Length"]))
                f.write(chunk)
            self.progresstick(path,f.tell(),int(pk.headers["Content-Length"]))

    def downloadpackage(self,name,version="default"):
        ver = self.getlatest(name) if version=="default" else self.checkver(name,version)
        if ver==DowErr.DOWNOVER: return DowErr.DOWNOPACKVER
        jd = self.session.get(self.mainurl+"/packages/"+name+"/package-"+ver+".tar",
                              headers=self.hdr,stream=True)
        if not (jd.status_code>=200 and jd.status_code<400): return DowErr.DOWNOPACKAGE
        jd.close()
        self.downloadpk(name,ver,".")
        print("")

    def getusrfolder(self):
        r = os.environ["PREFIX"] if os.name=="posix" else "???"

    def showhelp(self):
        print('''
dowgo install [package_name]
        ''')

if __name__=="__main__":
    version="1.0"
    print(f"DowGo! (Download and Go!) v{version} by NDRAEY")

    pars = OptionParser()
    (opts, args) = pars.parse_args()

    dow = DowGo()

    if not args: dow.showhelp(); sys.exit(1)

    if args[0]=="install":
        packages = args[1:]
        print(f"Getting lists from server {dow.mainurl}...")
        work = dow.getlists()
        if len(packages)>2:
            print(f"Searching {packages[0]}, {packages[1]} and {len(packages[1:])-1} more...")
        else:
            if len(packages)==2:
                print(f"Searching {packages[0]}, {packages[1]}...")
            elif len(packages)==1:
                print(f"Searching {packages[0]}...")
            else:
                print("No packages specifed!!!")
                sys.exit(1)
        
        for i in packages:
            if not (i.split("@")[0] in work):
                i=i.split("@")[0]
                print("\nPackage "+i+" not found...")
                sys.exit(1)
                
        for i in packages:
            ver = i.split("@")[-1]
            pkg = i.split("@")[0]
            if ver==i: ver="default"
            res = dow.downloadpackage(pkg,ver) # Result
            if res==DowErr.DOWNOPACKVER:
                print("\033[31mE:\033[0m No version ("+ver+") found for package "+pkg)
            elif res==DowErr.DOWNOPACKAGE:
                print("\033[31mE:\033[0m Could not download package "+pkg+"@"+ver)
    else:
        print("dowgo: Unknown parameter!!!")
        dow.showhelp()
        sys.exit(1)
