"""
provides utility functions for specific jasperreports upgrade 3.0 -> 3.1
"""

import os
import logging
import shutil

import basedefs30
import basedefs
import common_utils as utils

REPORTS_SERVER_DIR = "/var/lib/jbossas/server/rhevm-slimmed/deploy/rhevm-reports.war/"
REPORTS_SERVER_SCRIPTS_DIR = os.path.join(REPORTS_SERVER_DIR, "scripts")
MSG_ERROR_BACKUP_REPORTS_DB = "Reports database backup failed"
DIR_DEPLOY = "/usr/share/ovirt-engine"
FILE_JS_SMTP = "%s/WEB-INF/js.quartz.properties" % basedefs30.JS_WAR_PATH
REPORTS_BACKUP_FILE = os.path.join(basedefs.DIR_DB_BACKUPS, "ReportsWarBackup.bz2")
REPORTS_SCHEDULE_BACKUP_PATH = os.path.join(basedefs.DIR_DB_BACKUPS, "schedulesExports")
REPORTS_USERS_BACKUP_PATH = os.path.join(basedefs.DIR_DB_BACKUPS, "reportUsers")
REPORTS_ADHOC_BACKUP_PATH = os.path.join(basedefs.DIR_DB_BACKUPS, "adHocDomainsExport")


def backupJsInstallation():
    """docstring for backupJsInstallation"""

    # TAR basedefs30.JS_WAR_PATH
    logging.info("Backup JS WAR")
    cmd = [
        "/bin/tar",
        "cpPjf",
        REPORTS_BACKUP_FILE,
        basedefs30.JS_WAR_PATH,
    ]
    utils.execCmd(cmdList=cmd, failOnError=True, msg="Failed to backup previous Jasper installation")

    # backup DB
    logging.info("Backing up reports DB")
    backupReportsDb()

    # export users, ad-hoc reports and scheduled tasks
    logging.info("Exporting users, ad-hoc reports and scheduled tasks")
    exportSchedule()
    exportUsers()
    exportAdHoc()

    # backup smtp configuration
    logging.info("Backing up smtp configuration")
    backupSmtpConfig()

    # replace organization, update path to ad-hoc domain, remove old ad-hoc domains.
    logging.info("Upgrading configuration for higher version")
    upgradeConfigs()


def setUpgraded():
    # raise the upgrade flag
    with open(basedefs30.UPGRADE_FLAG, "w") as f:
        f.write("Upgraded")


def exportSchedule():
    """
    export scheduale reports to a temp direcotry
    """
    logging.debug("exporting scheduale reports")
    current_dir = os.getcwd()

    try:
        os.chdir(REPORTS_SERVER_SCRIPTS_DIR)

        # Export scheduale reports to a temp directory
        if os.path.exists(REPORTS_SCHEDULE_BACKUP_PATH):
            # Remove previous backup if exists
            logging.debug("Removing %s", REPORTS_SCHEDULE_BACKUP_PATH)
            shutil.rmtree(REPORTS_SCHEDULE_BACKUP_PATH)

        # Recreate the backup folder
        os.makedirs(REPORTS_SCHEDULE_BACKUP_PATH)
        cmd = [
            "./js-export.sh",
            "--output-dir", REPORTS_SCHEDULE_BACKUP_PATH,
            "--report-jobs", "/",
        ]
        utils.execCmd(cmdList=cmd, failOnError=True, msg="Failed while exporting scheduale reports")

    except:
        logging.error("Exception caught, passing it along to main loop")
        raise

    finally:
        os.chdir(current_dir)


def exportUsers():
    """
    export all users from jasper
    """
    logging.debug("exporting users from reports")
    current_dir = os.getcwd()

    # Remove previous backup if present
    if os.path.exists(REPORTS_USERS_BACKUP_PATH):
        logging.debug("Removing %s", REPORTS_USERS_BACKUP_PATH)
        shutil.rmtree(REPORTS_USERS_BACKUP_PATH)
    # Recreate a backup directory
    os.makedirs(REPORTS_USERS_BACKUP_PATH)
    logging.debug("backup directory: %s" % REPORTS_USERS_BACKUP_PATH)
    os.chdir(REPORTS_SERVER_SCRIPTS_DIR)

    # Export all users from jasper into the temp directory
    logging.debug("Exporting users to %s" % REPORTS_USERS_BACKUP_PATH)
    cmd = [
        "./js-export.sh",
        " --output-dir", REPORTS_USERS_BACKUP_PATH,
        "--users",
        "--roles",
    ]
    utils.execCmd(cmdList=cmd, failOnError=True, msg="Failed while exporting users")

    os.chdir(current_dir)
    return REPORTS_USERS_BACKUP_PATH


def exportAdHoc():
    """
    export AD HOC reports to a temp direcotry
    """
    logging.debug("exporting ad hoc reports")
    current_dir = os.getcwd()

    try:
        os.chdir(REPORTS_SERVER_SCRIPTS_DIR)

        # Remove previous backup if present
        if os.path.exists(REPORTS_ADHOC_BACKUP_PATH):
            logging.debug("Removing %s", REPORTS_ADHOC_BACKUP_PATH)
            shutil.rmtree(REPORTS_ADHOC_BACKUP_PATH)

        # Recreate a backup directory
        os.makedirs(REPORTS_ADHOC_BACKUP_PATH)
        cmd = [
            "./js-export.sh",
            "--output-dir", REPORTS_ADHOC_BACKUP_PATH,
            "--uris", "/organizations/rhevmreports/adhoc",
        ]
        utils.execCmd(cmdList=cmd, failOnError=True, msg="Failed while exporting ad hoc reports")

    except:
        logging.error("Exception caught, passing it along to main loop")
        raise

    finally:
        os.chdir(current_dir)


def backupSmtpConfig():
    backupSmtp = os.path.join(basedefs.DIR_DB_BACKUPS, "ReportsSmtpConf.bak")
    # Copy the SMTP configuration aside before we deploy the Jasper war
    smtpConfFile = FILE_JS_SMTP
    if os.path.exists(smtpConfFile):
        shutil.copy2(smtpConfFile, backupSmtp)


def backupReportsDb():
    logging.debug("Reports DB Backup started")
    #cmd = "%s -C -E UTF8 --column-inserts --disable-dollar-quoting  --disable-triggers -U %s -h %s -p %s --format=p -f %s %s"\
        #%(basedefs.EXEC_PGDUMP, SERVER_ADMIN, SERVER_HOST, SERVER_PORT, self.sqlfile, basedefs.DB_NAME)

    BACKUP_FILE = "reports_db_backup"
    date = utils.getCurrentDateTime()
    sqlfile = "%s/%s_%s.sql" % (basedefs.DIR_DB_BACKUPS, BACKUP_FILE, date)
    cmd = [
        basedefs.EXEC_PGDUMP,
        "-C", "-E", "UTF8",
        "--column-inserts",
        "--disable-dollar-quoting",
        "--disable-triggers",
        "-U", "postgres",
        "--format=p",
        "-f", sqlfile,
        basedefs30.REPORTS_DB_NAME,
    ]
    output, rc = utils.execCmd(cmdList=cmd, failOnError=True, msg=MSG_ERROR_BACKUP_REPORTS_DB, envDict=utils.getPgPassEnv())
    logging.debug("Reports DB Backup completed successfully")


def upgradeConfigs():
    """docstring for upgradeConfigs"""
    orgAdHocPath = os.path.join(REPORTS_ADHOC_BACKUP_PATH, "resources", "organizations")
    orgSchedulePath = os.path.join(REPORTS_SCHEDULE_BACKUP_PATH, "reportJobs", "organizations")

    # Recreate a new adHoc folder structure
    adhocDomainsPath = os.path.join(orgAdHocPath, "rhevmreports", "adhoc", "Domains")
    if os.path.exists(adhocDomainsPath):
        tempAdhocPath = adhocDomainsPath.replace("rhevmreports/adhoc/Domains", "rhevmreports/adhoc/3_0")
        os.rename(adhocDomainsPath, tempAdhocPath)
        os.makedirs(adhocDomainsPath)
        shutil.move(tempAdhocPath, adhocDomainsPath)

    # Replace rhevmreports organization with organization_1 in folder structure
    for orgPath in (orgAdHocPath, orgSchedulePath):
        oldPath = os.path.join(orgPath, "rhevmreports")
        newPath = os.path.join(orgPath, "organization_1")
        if os.path.exists(oldPath):
            os.rename(oldPath, newPath)

    for p in ("roles", "users"):
        usersPath = os.path.join(REPORTS_USERS_BACKUP_PATH, p)
        rhevmPath = os.path.join(usersPath, "rhevmreports")
        organizationPath = os.path.join(usersPath, "organization_1")
        if os.path.exists(rhevmPath):
            os.rename(rhevmPath, organizationPath)

    # Rename recursively all "rhevmreports" organizations to "organization_1" in files
    # 1. Find all files in the folders:
    files = []
    for orgPath in (REPORTS_ADHOC_BACKUP_PATH, REPORTS_SCHEDULE_BACKUP_PATH, REPORTS_USERS_BACKUP_PATH):
        for f in os.walk(orgPath):
            if len(f[2]) > 0:
                for nf in f[2]:
                    files.append(os.path.join(f[0], nf))

    # 2. Go over each file and replace 'rhevmreports' with 'organization_1'
    for mfile in files:
        logging.debug("Updating configuration file %s", mfile)
        newlines = []
        with open(mfile) as f:
            for line in f.readlines():
                line = line.replace("rhevmreports", "organization_1")
                line = line.replace("/Domains", "/Domains/3_0")
                newlines.append(line)

        with open(mfile, 'w') as out:
            for line in newlines:
                out.write(line)

    # Handle .folder.xml files
    folderFile3_0 = os.path.join(orgAdHocPath, "organization_1", "adhoc", "Domains", "3_0", ".folder.xml")
    folderFileDomains = os.path.join(orgAdHocPath, "organization_1", "adhoc", "Domains", ".folder.xml")
    # First, copy the .folder.xml from 3_0 to Domains
    shutil.copy(folderFile3_0, folderFileDomains)

    # Now, update .folder.xml in 3_0
    newlines = []
    with open(folderFile3_0) as f:
        for line in f.readlines():
            line = line.replace("organization_1/adhoc", "organization_1/adhoc/Domains")
            line = line.replace("<name>Domains</name>", "<name>3_0</name>")
            line = line.replace("<label>Domains</label>", "<label>3.0</label>")
            newlines.append(line)
    with open(folderFile3_0, 'w') as out:
            for line in newlines:
                out.write(line)

    # Update .folder.xml in Domains
    newlines = []
    with open(folderFileDomains) as f:
        for line in f.readlines():
            if not '<resource>' in line:
                newlines.append(line)

    with open(folderFileDomains, 'w') as out:
        for line in newlines:
            out.write(line)
