# Code to download and update fake repositories
#
#
#
# CREDIT TODO

# Imports
import re, datetime, urllib.request, os

import subprocess

from ivulncheck_api.lib.config_api import Configuration as conf

import logging
logging.basicConfig(filename=conf.getLogfile(), level=logging.INFO)


def update_ubuntu_cve_tracker():
    UCT_BRANCH=conf.getUCTBranch()
    UCT_PATH=conf.getUCTPath()
    

    try:
        if not os.path.exists(UCT_PATH + "/scripts"):
            logging.info('[%s] (%s)\tDownloading ubuntu-cve-tracker.', datetime.datetime.today().isoformat(), __name__)
            p = subprocess.Popen(["bzr", "branch", UCT_BRANCH, UCT_PATH], stdout=subprocess.PIPE)
            (out, err) = p.communicate()
            if err is None:
                logging.info('[%s] (%s)\tubuntu-cve-tracker downloaded.', datetime.datetime.today().isoformat(), __name__)
            else:
                logging.error('[%s] (%s)\t%s.', datetime.datetime.today().isoformat(), __name__, err)
                return False
        
        p = subprocess.Popen(["bzr", "pull"], cwd=UCT_PATH, stdout=subprocess.PIPE)
        (out, err) = p.communicate()
        if err is None:
            logging.info('[%s] (%s)\tubuntu-cve-tracker updated.', datetime.datetime.today().isoformat(), __name__)
        else:
            logging.error('[%s] (%s)\t%s.', datetime.datetime.today().isoformat(), __name__, err)
            return False
        
        
        subprocess.Popen(["sed", "-i", "s#^outPath=.*#outPath=" +  UCT_PATH + "/ubuntu-archive-metadata#", UCT_PATH + "/scripts/packages-mirror"])
        subprocess.Popen(["sed", "-i", "s#^debianPath=.*#debianPath=" +  UCT_PATH + "/debian-testing-archive-metadata#", UCT_PATH + "/scripts/packages-mirror"])
        subprocess.Popen(["sed", "-i", "s#^partnerPath=.*#partnerPath=" +  UCT_PATH + "/partner-archive-metadata#", UCT_PATH + "/scripts/packages-mirror"])
        
        # Wait undefinately => moved to ivulncheck_download bash script
        # ~ p = subprocess.Popen(["./scripts/packages-mirror"], cwd=UCT_PATH, stdout=subprocess.PIPE)
        # ~ return_code = p.wait()
        # ~ logging.info('[%s] (%s)\tUbuntu Archive download returned : %d.', datetime.datetime.today().isoformat(), __name__, return_code)
        # ~ p = subprocess.Popen(["./scripts/packages-mirror", "-p"], cwd=UCT_PATH, stdout=subprocess.PIPE)
        # ~ return_code = p.wait()
        # ~ logging.info('[%s] (%s)\tPartner Archive download returned : %d.', datetime.datetime.today().isoformat(), __name__, return_code)
        
        return True
        
    except Exception as e:
        logging.error('[%s] (%s)\t%s during downloading or updating ubuntu-cve-tracker.', datetime.datetime.today().isoformat(), __name__, str(e))
        return False
        

def download_fake_repos(db):
    
    FAKE_REPOS_PATH=conf.getFakeReposPath()
    DEBIAN_ARCHIVE_URL=conf.getDebianArchiveURL()
    DEBIAN_SECURITY_ARCHIVE_URL=conf.getDebianSecurityArchiveURL()
    UBUNTU_ARCHIVE_URL=conf.getUbuntuArchiveURL()
    
    try:
        if not os.path.exists(FAKE_REPOS_PATH + "/debian"):
            os.makedirs(FAKE_REPOS_PATH + "/debian")
            os.makedirs(FAKE_REPOS_PATH + "/debian/dists")
        if not os.path.exists(FAKE_REPOS_PATH + "/debian-security"):
            os.makedirs(FAKE_REPOS_PATH + "/debian-security")
            os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists")
            
        suites = db.getSuites()
        for suite in suites:
            if not os.path.exists(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates"):
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates")
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/main")
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/main/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/contrib")
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/contrib/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/non-free")
                os.makedirs(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/non-free/binary-amd64")
            
            fw1 = open(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/main/binary-amd64/Packages.gz", 'wb+')
            fw1.write(urllib.request.urlopen(DEBIAN_ARCHIVE_URL + suite + "-proposed-updates/main/binary-amd64/Packages.gz").read())
            fw1.close()
            
            fw2 = open(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/contrib/binary-amd64/Packages.gz", 'wb+')
            fw2.write(urllib.request.urlopen(DEBIAN_ARCHIVE_URL + suite + "-proposed-updates/contrib/binary-amd64/Packages.gz").read())
            fw2.close()
            
            fw3 = open(FAKE_REPOS_PATH + "/debian/dists/" + suite + "-proposed-updates/non-free/binary-amd64/Packages.gz", 'wb+')
            fw3.write(urllib.request.urlopen(DEBIAN_ARCHIVE_URL + suite + "-proposed-updates/non-free/binary-amd64/Packages.gz").read())
            fw3.close()
            
            if not os.path.exists(FAKE_REPOS_PATH + "/debian-security/dists/" + suite):
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite)
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/main")
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/main/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/contrib")
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/contrib/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/non-free")
                os.makedirs(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/non-free/binary-amd64")
            
            fw4 = open(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/main/binary-amd64/Packages.gz", 'wb+')
            fw4.write(urllib.request.urlopen(DEBIAN_SECURITY_ARCHIVE_URL + suite + "/updates/main/binary-amd64/Packages.gz").read())
            fw4.close()
            
            fw5 = open(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/contrib/binary-amd64/Packages.gz", 'wb+')
            fw5.write(urllib.request.urlopen(DEBIAN_SECURITY_ARCHIVE_URL + suite + "/updates/contrib/binary-amd64/Packages.gz").read())
            fw5.close()
            
            fw6 = open(FAKE_REPOS_PATH + "/debian-security/dists/" + suite + "/non-free/binary-amd64/Packages.gz", 'wb+')
            fw6.write(urllib.request.urlopen(DEBIAN_SECURITY_ARCHIVE_URL + suite + "/updates/non-free/binary-amd64/Packages.gz").read())
            fw6.close()
            
            logging.info('[%s] (%s)\tFake repo for Debian %s downloaded.', datetime.datetime.today().isoformat(), __name__, suite)
            
            
        if not os.path.exists(FAKE_REPOS_PATH + "/ubuntu"):
            os.makedirs(FAKE_REPOS_PATH + "/ubuntu")
            os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists")
        releases = db.getReleases()
        for release in releases:
            if not os.path.exists(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed"): 
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/main")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/main/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/multiverse")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/multiverse/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/restricted")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/restricted/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/universe")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/universe/binary-amd64")
                
            fw1 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/main/binary-amd64/Packages.gz", 'wb+')
            fw1.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-proposed/main/binary-amd64/Packages.gz").read())
            fw1.close()
            
                
            fw2 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/multiverse/binary-amd64/Packages.gz", 'wb+')
            fw2.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-proposed/multiverse/binary-amd64/Packages.gz").read())
            fw2.close()
            
            
            fw3 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/restricted/binary-amd64/Packages.gz", 'wb+')
            fw3.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-proposed/restricted/binary-amd64/Packages.gz").read())
            fw3.close()
            
            
            fw4 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-proposed/universe/binary-amd64/Packages.gz", 'wb+')
            fw4.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-proposed/universe/binary-amd64/Packages.gz").read())
            fw4.close()
            
            if not os.path.exists(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security"): 
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/main")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/main/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/multiverse")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/multiverse/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/restricted")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/restricted/binary-amd64")
                
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/universe")
                os.makedirs(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/universe/binary-amd64")
                
            fw5 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/main/binary-amd64/Packages.gz", 'wb+')
            fw5.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-security/main/binary-amd64/Packages.gz").read())
            fw5.close()
            
                
            fw6 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/multiverse/binary-amd64/Packages.gz", 'wb+')
            fw6.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-security/multiverse/binary-amd64/Packages.gz").read())
            fw6.close()
            
            
            fw7 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/restricted/binary-amd64/Packages.gz", 'wb+')
            fw7.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-security/restricted/binary-amd64/Packages.gz").read())
            fw7.close()
            
            
            fw8 = open(FAKE_REPOS_PATH + "/ubuntu/dists/" + release + "-security/universe/binary-amd64/Packages.gz", 'wb+')
            fw8.write(urllib.request.urlopen(UBUNTU_ARCHIVE_URL + release + "-security/universe/binary-amd64/Packages.gz").read())
            fw8.close()
    
            logging.info('[%s] (%s)\tFake repo for Ubuntu %s downloaded.', datetime.datetime.today().isoformat(), __name__, release)
        return True
        
    except Exception as e:
        logging.info('[%s] (%s)\t%s during downloading fake repos.', datetime.datetime.today().isoformat(), __name__, str(type(e)))
        return False
