#!/usr/bin/python3
## -*- coding: utf-8 -*-
#
# Copyright (C) 2011, Thomas Mashos, for Mythbuntu
#
# Mythbuntu-bare 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.
#
# This program 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 this application; if not, write to the Free Software Foundation, Inc., 51
# Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
##################################################################################
import os
import tarfile
import time
import shutil
import subprocess
import platform
import configparser
import logging
import datetime

logger = logging.getLogger('mythbuntu-bare')
hdlr = logging.FileHandler('/var/log/mythbuntu-bare-client.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)

ACTOR="<mythbackup> "

class Backup():

    def backup_job(self, BackupDB=True, Location="/var/lib/mythtv/bare-client/"):
        """Backup all the files"""
        logger.info(ACTOR+'Starting backup job')
        ## Check backup directory exists
        if Location == "U1" or Location == "DROPBOX":
            logger.info(ACTOR+'Configured to backup to: '+str(Location))
        elif not os.path.exists(Location):
            os.makedirs(Location)
            logger.info(ACTOR+'Creating backup directory at '+str(Location))
        ## Array of files to Backup
        BACKUPFILES = [
        "/etc/mythtv/config.xml",
        "/etc/mythtv/mysql.txt",
        "/etc/lirc/lircd.conf",
        "/etc/lirc/hardware.conf",
        "/etc/hostname",
        "/etc/hosts",
        ]
        USER=os.getenv("HOME")
        logger.info(ACTOR+'Setting files to backup')
        BACKUPFILES.append(USER+"/.lirc")
        ## Set up backup location
        TMPDIR="/tmp/mythbuntu-bare"
        logger.info(ACTOR+'Creating temp directory at '+str(TMPDIR))
        if not os.path.exists(TMPDIR):
            os.makedirs(TMPDIR)
        BACKUPFILES.append(TMPDIR)
        ## Set status file
        STATUSFILE="/tmp/mythbuntu-bare-status"
        logger.info(ACTOR+'Setting status file to '+str(STATUSFILE))
        if os.path.isfile(STATUSFILE):
            os.remove(STATUSFILE)
        timestamp=time.strftime("%Y%m%d-%H%M", time.localtime())
        ## Backup database only if told to do so
        DBB=""
        MBE=""
        logger.info(ACTOR+'Detecting Master Backend')
        if os.path.isdir("/usr/share/doc/mythtv-backend-master"):
            logger.info(ACTOR+'Master Backend status is True')
            MBE="_MBE"
            DBB="_NODB"
            if BackupDB == '1' or BackupDB == True or BackupDB == "True":
                logger.info(ACTOR+'Backing up database')
                #Run DB Backup
                os.system("echo '20\nBacking up database (this could take a few minutes)'>"+STATUSFILE)
                backupscript="/usr/share/mythtv/mythconverg_backup.pl"
                pipe = subprocess.Popen([backupscript, '--directory', TMPDIR], stdout=subprocess.PIPE).communicate()
                DBB="_YESDB"
            else:
                logger.info(ACTOR+'Database set to not be backed up')
        else:
            logger.info(ACTOR+'Master Backend status is False')
        ## Setup for final tar file
        hostname = platform.node()
        logger.info(ACTOR+'Hostname is '+str(hostname))
#        tarfilename=Location+'/mythbuntu-system-backup_'+hostname+'_'+timestamp+MBE+DBB+'.tar.gz'
        tarfilename='mythbuntu-system-backup_'+hostname+'_'+timestamp+MBE+DBB+'.tar.gz'
        logger.info(ACTOR+'Tarfile is '+str(tarfilename))
        TF=tarfile.open("/tmp/"+tarfilename,mode='w:gz')
        os.system("echo '90\nZipping up files'>"+STATUSFILE)
        ## Add files to tarball
        logger.info(ACTOR+'Backing up files')
        for item in BACKUPFILES:
            if os.path.exists(item):
                TF.add(item)
        TF.close()
        ## Check if managed and push file to server if necessary
        if os.path.isfile("/var/lib/mythtv/bare-client/mythbuntu-bare-client.conf"):
            config = configparser.ConfigParser()
            config.read("/var/lib/mythtv/bare-client/mythbuntu-bare-client.conf")
            managed = config.get("General", "managed")
        else:
            managed = False
        ## Set last backup time
        lastbackupname="lastbackuptime-"+hostname+".log"
        lbt = open("/tmp/"+lastbackupname, 'w')
        lbt.write(str(datetime.datetime.now()))
        lbt.close()
        ## Copy files to backup location
        logger.info(ACTOR+'Copying backup file to: '+Location)
        if Location == "U1":
            import u1files
            u1 = u1files.U1Files()
            u1.login()
            u1.put("/tmp/"+tarfilename, "mythbuntu-bare/"+tarfilename)
            u1.put("/tmp/"+lastbackupname, "mythbuntu-bare/"+lastbackupname)
        elif Location == "DROPBOX":
            ## TODO
            pass
        else:
            shutil.move("/tmp/"+tarfilename, Location+"/"+tarfilename)
            shutil.move("/tmp/"+lastbackupname, Location+"/"+lastbackupname)
#        if managed:
#            logger.info(ACTOR+'Pushing backup file to server')
#            ServerIP = config.get("General", "serverip")
#            ServerPort = config.get("General", "serverport")
#            pipe = subprocess.Popen(["/usr/share/mythbuntu-bare/bareclient/bare/push_file.py", 'http://'+ServerIP+":"+ServerPort+"/cgi-bin/save_file.py", tarfilename], stdout=subprocess.PIPE).communicate()
#        else:
#            logger.info(ACTOR+'Machine unmanaged')

        ## Remove tmp Backup directory and status file
        logger.info(ACTOR+'Removing temp files')
        if os.path.exists(TMPDIR):
            shutil.rmtree(TMPDIR)
        if os.path.isfile(STATUSFILE):
            os.remove(STATUSFILE)
        logger.info(ACTOR+'Backup job finished')

if __name__ == "__main__":
    ACTOR="<backup-task> "

    CONFIGFILENAME = "mythbuntu-bare-client.conf"
    CONFIGPATH = "/var/lib/mythtv/bare-client/"
    CONFIGFILE = CONFIGPATH+CONFIGFILENAME

    ## Read config file
    config = configparser.ConfigParser()
    config.read(CONFIGFILE)

    logger.info(ACTOR+'Initializing backup settings')

    ## Check if managed and if so, then update
    managed = config.get("General", "managed")
    logger.info(ACTOR+'Checking if managed: '+str(managed))
    if managed:
        pipe = subprocess.Popen(["/usr/share/mythbuntu-bare/bareclient/mythbareupdate.py"], stdout=subprocess.PIPE).communicate()

    ## Reread config file in case it was updated
    config.read(CONFIGFILE)
    DB = config.get("Backup", "db")
    logger.info(ACTOR+'Setting database backup to '+str(DB))
    storagedir = config.get("Backup", "storagedir")
    logger.info(ACTOR+'Setting backup storage directory to '+str(storagedir))

    ## Run backup job
    logger.info(ACTOR+'Starting backup job')
    Backup().backup_job(DB, storagedir)
