#!/usr/bin/env python3
# Copyright (C) 2023 Stewart Adam
# This file is part of fwbackups.

# fwbackups is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# fwbackups is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with fwbackups; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import os
import sys
import time
import getopt
import signal

launched_from = os.path.dirname(os.path.realpath(__file__))
if os.path.exists(os.path.join(launched_from, '../fwbackups/__init__.py')):  # check if we are running from source
    sys.path.append('../fwbackups')

import fwbackups
from fwbackups.i18n import _
from fwbackups import const as constants
from fwbackups.operations import backup
from fwbackups import config
from fwbackups import fwlogger

if constants.IS_FLATPAK and 'XDG_RUNTIME_DIR' in os.environ and 'FLATPAK_ID' in os.environ:
    XDG_RUNTIME_DIR = os.environ.get('XDG_RUNTIME_DIR')
    FLATPAK_ID = os.environ.get('FLATPAK_ID')
    os.environ['TMPDIR'] = f"{XDG_RUNTIME_DIR}/app/{FLATPAK_ID}"


def usage(error=None):
    if error:
        print(_('Error: %s' % error))
        print(_('Run with --help for usage information.'))
    else:
        print(_("""Usage: fwbackups-run [OPTIONS] Set_Name(s)
Options:
  -v, --verbose  :  Increase verbosity (print debug messages)
  -h, --help  :  Print this message and exit
  -l, --silent  :  Print messages to log file only
  -f, --force :  Run the backup even if the set is disabled.

Set_Name(s) is space-seperated list of set names to run backups of."""))


def handleStop(arg1, arg2):
    """ Handles a sigint """
    backupHandle.cancelOperation()


# Only if we're in main execution
if __name__ == "__main__":
    verbose = False
    printToo = True
    forceRun = False
    try:
        avalableOptions = ["help", "verbose", "silent", "force"]
        # letter = plain options
        # letter: = option with arg
        (opts, rest_args) = getopt.gnu_getopt(sys.argv[1:], "hvlf", avalableOptions)
    except (getopt.GetoptError) as e:
        usage(e)
        sys.exit(1)
    # Remove options from paths
    sets = [setPath for setPath in sys.argv[1:]]
    for i in opts:
        for ii in i:
            try:
                sets.remove(ii)
            except BaseException:
                pass
    # Parse args, take action
    if opts == []:
        pass
    else:
        for (opt, value) in opts:
            if opt == "-h" or opt == "--help":
                usage()
                sys.exit(1)
            if opt == "-v" or opt == "--verbose":
                verbose = True
            if opt == "-l" or opt == "--silent":
                printToo = False
            if opt == "-f" or opt == "--force":
                forceRun = True
    if not len(sets) >= 1:
        usage(_('Invalid usage: Requires at least one set name to backup'))
        sys.exit(1)
    prefs = config.PrefsConf(create=True)
    if verbose == True or int(prefs.get('Preferences', 'AlwaysShowDebug')) == 1:
        level = fwlogger.L_DEBUG
    else:
        level = fwlogger.L_INFO
    logger = fwlogger.getLogger()
    logger.setLevel(level)
    logger.setPrintToo(printToo)
    # handle ctrl + c
    signal.signal(signal.SIGINT, handleStop)
    for setPath in sets:
        if constants.MSWINDOWS:
            setPath = setPath.strip("'")
        setPath = os.path.join(constants.SETLOC, "%s.conf" % setPath)
        if not os.path.exists(setPath):
            logger.logmsg("ERROR", _("The set configuration for '%s' was not found - skipping." % setPath))
            continue
        try:
            backupHandle = backup.SetBackupOperation(setPath, logger=logger, forceRun=forceRun)
            backupThread = fwbackups.FuncAsThread(backupHandle.start, {})
        except Exception as error:
            import traceback
            (etype, evalue, tb) = sys.exc_info()
            tracebackText = ''.join(traceback.format_exception(etype, evalue, tb))
            logger.setPrintToo(True)
            logger.logmsg('WARNING', _("An error occurred while initializing the backup operation!"))
            logger.logmsg('ERROR', tracebackText)
            sys.exit(1)
        backupThread.start()
        try:
            while backupThread.retval is None:
                time.sleep(0.1)
        except IOError:  # ctrl+c raises this on Win32
            print('IOError while sleep!')
        # thread returned
        logger.logmsg('DEBUG', _('Thread returned with retval %s' % backupThread.retval))
        if backupThread.retval == -1:
            logger.logmsg('WARNING', _('There was an error while performing the backup!'))
            logger.logmsg('ERROR', backupThread.traceback)
