#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 18 14:53:00 2020

@author: fatih
"""

import os
import random
import string
import subprocess
import sys
from datetime import datetime
from pathlib import Path
from shutil import rmtree

import apt
import apt_pkg
import distro


def main():
    def control_lock():
        msg = ""
        apt_pkg.init_system()
        try:
            apt_pkg.pkgsystem_lock()
        except SystemError as e:
            msg = "{}".format(e)
            print("ufficiozero-software: {}".format(msg), file=sys.stderr)
            return False, msg
        apt_pkg.pkgsystem_unlock()
        return True, msg

    def update():
        try:
            cache = apt.Cache()
            cache.update()
            cache.open()
        except Exception as e:
            print(str(e))
            subupdate()

    def subupdate():
        subprocess.call(["apt", "update"],
                        env={**os.environ, 'DEBIAN_FRONTEND': 'noninteractive'})

    def subupgrade(yq, dpkg_conf):

        lock, msg = control_lock()
        if not lock:
            if "E:" in msg and "/var/lib/dpkg/lock-frontend" in msg:
                print("dpkg lock error", file=sys.stderr)
                sys.exit(11)
            elif "E:" in msg and "dpkg --configure -a" in msg:
                print("dpkg interrupt error", file=sys.stderr)
                sys.exit(12)

        dpkg_conf_list = dpkg_conf.split(" ")
        yq_list = yq.split(" ")
        subprocess.call(["apt", "full-upgrade"] + yq_list + dpkg_conf_list,
                        env={**os.environ, 'DEBIAN_FRONTEND': 'noninteractive'})

    def fixbroken():
        subprocess.call(["apt", "install", "--fix-broken", "-yq"],
                        env={**os.environ, 'DEBIAN_FRONTEND': 'noninteractive'})

    def dpkgconfigure():
        subprocess.call(["dpkg", "--configure", "-a"],
                        env={**os.environ, 'DEBIAN_FRONTEND': 'noninteractive'})

    def aptclean():
        subprocess.call(["apt", "clean"],
                        env={**os.environ, 'DEBIAN_FRONTEND': 'noninteractive'})

    def externalrepo(key, sources, name):
        tmpkeyfilename = ''.join(random.choice(string.ascii_lowercase) for i in range(13))
        tmpkeyfile = open(os.path.join("/tmp", tmpkeyfilename), "w")
        tmpkeyfile.write(key)
        tmpkeyfile.flush()
        tmpkeyfile.close()
        tmpkey = os.path.join("/tmp", tmpkeyfilename)

        subprocess.call(["apt-key", "add", tmpkey])

        Path("/etc/apt/sources.list.d/").mkdir(parents=True, exist_ok=True)
        sdfile = open("/etc/apt/sources.list.d/" + name, "w")
        sdfile.write(sources)
        sdfile.flush()
        sdfile.close()

        if os.path.isfile(tmpkey):
            os.remove(tmpkey)

    def correctsourceslist():
        found = True
        source = ""
        major = distro.major_version()
        codename = distro.codename().lower()
        now = datetime.now()

        if codename == "daedalus":
            source = "### The Official Devuan Package Repositories ###\n\n" \
                     "deb http://deb.devuan.org/merged daedalus main non-free-firmware\n" \
                     "# deb-src http://deb.devuan.org/merged daedalus main non-free-firmware\n\n" \
                     "deb http://deb.devuan.org/merged daedalus-updates main non-free-firmware\n" \
                     "# deb-src http://deb.devuan.org/merged daedalus-updates main non-free-firmware\n\n" \
                     "deb http://deb.devuan.org/merged daedalus-security main non-free-firmware\n" \
                     "# deb-src http://deb.devuan.org/merged daedalus-security main non-free-firmware\n\n" \
                     "deb http://deb.devuan.org/merged daedalus-proposed-updates main non-free-firmware\n" \
                     "# deb-src http://deb.devuan.org/merged daedalus-proposed-updates main non-free-firmware\n\n" \
		     "deb http://deb.devuan.org/merged daedalus-backports main non-free-firmware\n" \
                     "# deb-src http://deb.devuan.org/merged daedalus-backports main non-free-firmware\n\n" \	
                     "deb https://ufficiozero.mirror.garr.it/uzl-deb/minimal/ minimal main contrib non-free\n" \
                     "### This section generated by Pardus Software at " + str(now) + " ###\n"
                             
        else:
            found = False

        if found:
            sdir = "/etc/apt/sources.list.d"
            if os.path.isdir(sdir):
                slistd = os.listdir(sdir)
                for slist in slistd:
                    commented = ""
                    if slist.endswith(".list"):
                        try:
                            with open(os.path.join(sdir, slist), "r") as sread:
                                for line in sread.readlines():
                                    commented += "#{}".format(line)
                            with open(os.path.join(sdir, slist), "w") as swrite:
                                swrite.writelines(commented)
                                swrite.flush()
                                swrite.close()
                        except Exception as e:
                            print("{}".format(e))

            sfile = open("/etc/apt/sources.list", "w")
            sfile.write(source)
            sfile.flush()
            sfile.close()

            rmtree("/var/lib/apt/lists/", ignore_errors=True)
            aptclean()

    if len(sys.argv) > 1:
        if sys.argv[1] == "externalrepo":
            externalrepo(sys.argv[2], sys.argv[3], sys.argv[4])
            update()
        elif sys.argv[1] == "correctsourceslist":
            correctsourceslist()
            subupdate()
        elif sys.argv[1] == "update":
            update()
        elif sys.argv[1] == "fixapt":
            correctsourceslist()
            subupdate()
            dpkgconfigure()
            fixbroken()
        elif sys.argv[1] == "upgrade":
            subupdate()
            subupgrade(sys.argv[2], sys.argv[3])
        elif sys.argv[1] == "dpkgconfigure":
            dpkgconfigure()
        else:
            print("unknown argument error")
    else:
        print("no argument passed")


if __name__ == "__main__":
    main()
