#!/usr/bin/python3
import os
import subprocess
import logging
import re
import sys
import time
import tempfile
import dbus

def usage():
    # Help screen
    print("Usage:")
    print('\t' + os.path.basename(__file__) + ' [command]')
    print('Available commands:')
    print('\t status \t Get service status')
    print('\t enable \t Enable service')
    print('\t disable \t Disable service')
    print('\t edit \t\t Open the config to editing')
    print('\t parameters\t Print a list of parameters available for editing')     
    print('\t set STATUS\t Set service to STATUS [stopped]')
    return -1

def enable_service():
    process = subprocess.run(["systemctl", "enable", "astra-update-service"])
    if process.returncode != 0:
        print("Failed to enable unit 'astra-update-service'")
        return 1
    else:
        process = subprocess.run(["systemctl", "start", "astra-update-service"])
        if process.returncode != 0:
            print("Failed to enable unit 'astra-update-service'")
            return 2
#    process = subprocess.run(["systemctl", "enable", "astra-upgrade"])
#    if process.returncode != 0:
#       print("Failed to enable unit 'astra-upgrade'")
#        return 3
    time.sleep(1)
    set_state("stopped", True)
    return 0

def disable_service():
    if get_status_by_dbus(False) == 0:
        set_state("no-updates", True)
    else:
        print("cannot set no-updates state: already disabled or broken service")
    process = subprocess.run(["systemctl", "stop", "astra-update-service"])
    if process.returncode != 0:
        print("Failed to stop unit 'astra-update-service'")
        return 1
    else:
        process = subprocess.run(["systemctl", "disable", "astra-update-service"])    
        if process.returncode != 0:
            print("Failed to disable unit 'astra-update-service'")
            return 2
#    process = subprocess.run(["systemctl", "disable", "astra-upgrade"])
#    if process.returncode != 0:
#        print("Failed to disable unit 'astra-upgrade'")
#        return 3
    return 0
    
def set_state(state, internal = False):
    if get_status_by_dbus(False) != 0:
        print("cannot set state: service disabled or broken")
        return 31
    correct_states = ["no-updates", "ready", "activated", "stopped", "force"]
    masked_states = ["stopped"]
    if state not in masked_states and internal == False:
        print("wrong state")
        return 33
    if state not in correct_states:
        print("wrong state")
        return 32
    index = correct_states.index(state)
    session_bus = dbus.SystemBus()
    eth0 = session_bus.get_object('ru.astralinux.fly.astraupdateservice',
                          '/ru/astralinux/fly/astraupdateservice')
    eth0_dev_iface = dbus.Interface(eth0,
                                    dbus_interface='ru.astralinux.fly.astraupdateservice')
    props = eth0_dev_iface.setStateFromOutside(index)
    if (props != 0):
        print("Perhaps, something went wrong. Please, pay your attention.")
    else:
        for i in range(5):
            msg = str("New state applying: " + str(5 - i) + " secs")
            print(msg)
            time.sleep(1)
    return props
    
def get_status_by_dbus(printres):
    disabled_counter = 0
    active_flag = False
#    process = subprocess.Popen(["systemctl", "is-enabled", "astra-update-service"], stdout=subprocess.DEVNULL, text=True)
#    process.wait()
    process = subprocess.Popen(["systemctl", "status", "astra-update-service"], stdout=subprocess.PIPE, text=True)
    enabled = False
    for s in process.stdout.readlines():
        if s.find("service.service; enabled") > 0:
            enabled = True
            break
#    if process.returncode != 0:
    if enabled == False:
        disabled_counter += 1
#    enabled = False
#    process = subprocess.Popen(["systemctl", "is-enabled", "astra-upgrade"], stdout=subprocess.DEVNULL, text=True)
#    process.wait()
#    process = subprocess.Popen(["systemctl", "status", "astra-upgrade"], stdout=subprocess.PIPE, text=True)
#    for s in process.stdout.readlines():
#        if s.find("upgrade.service; enabled") > 0:
#            enabled = True
#            break
#    if process.returncode != 0:
#    if enabled == False:
#        disabled_counter += 1
    if disabled_counter == 1:
        print("disabled")
        return 2
#    if disabled_counter == 1:
#        print("partially disabled")
 #       return 1
    process = subprocess.Popen(["systemctl", "is-active", "astra-update-service"], stdout=subprocess.DEVNULL, text=True)
    process.wait()
    if process.returncode == 0:
        active_flag = True
    if ( not active_flag ):
        print("the service is enabled, but not active")
        return 3
    if printres:
        session_bus = dbus.SystemBus()
        eth0 = session_bus.get_object('ru.astralinux.fly.astraupdateservice',
                          '/ru/astralinux/fly/astraupdateservice')
        eth0_dev_iface = dbus.Interface(eth0,
                                    dbus_interface='ru.astralinux.fly.astraupdateservice')
        props =  eth0_dev_iface.getCurrentStateAsString()
        print(props)
    return 0


def print_params():
    print('Available parameters:')
    print('\t T_check \t\t Interval between checks for updates [m], default = 60')
    print('\t T_download_min \t Minimum time before downloading updates [m], default = 0')
    print('\t T_download_max \t Maximum time before downloading updates [m], default = 240')
    print('\t T_delay \t\t Time to the system upgrade [d], default = 7')
    print('\t T_retry \t\t Time to the next attempt to the system update [h], default = 4')
    print('\t Action_on_error \t Action after update error [ Reset, Stop, Retry ]')    
    print('\t Always_new_update \t Remove downloaded updates before downloading new updates [false, true], default = false')     
    print('\t Host_to_ping \t\t Host to be pinged for checking network connection, default = 8.8.8.8')     
    return -1

    
def edit_config():
    subprocess.run(["edit", "text/plain:/etc/astra-update-service/astra-update-daemon.conf"])
    return 0


def check_arg():
    if len(sys.argv) - 1 == 0:
        return usage()
    else:
        if sys.argv[1] == "status":
            return get_status_by_dbus(True)
        if sys.argv[1] == "enable":
            return enable_service()          
        if sys.argv[1] == "disable":
            return disable_service()          
        if sys.argv[1] == "edit":
            return edit_config()                      
        if sys.argv[1] == "parameters":
            return print_params()                     
        if sys.argv[1] == "set":
            if len(sys.argv) < 3:
                return usage()
            else:
                return set_state(sys.argv[2])
            return
        return usage()

exit(check_arg())
