#!/usr/bin/env python
"""
 *
 * This file is part of rasdaman community.
 *
 * Rasdaman community 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 3 of the License, or
 * (at your option) any later version.
 *
 * Rasdaman community 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 rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2003 - 2016 Peter Baumann / rasdaman GmbH.
 *
 * For more information please see <http://www.rasdaman.org>
 * or contact Peter Baumann via <baumann@rasdaman.com>.
 *
"""
# make sure all string literals are unicode
from __future__ import unicode_literals
import os
import sys

from config_manager import ConfigManager
from util.executor import ExecutionError
from util.log import log
from util.prompt import ChangeSeverity, user_confirmed_change, set_severity_choice
from profile.profile import Profile, ProfileException
from strategies.strategy_builder import StrategyBuilder
from tester.tester import TestResultStatus
from util.updater import Updater


def bye_message(profile):
    """
    Prints a good bye message if all went well.
    :param Profile profile: the profile used to install
    """
    if profile.install and profile.generate_package is False:
        log.title("Next steps")
        log.info(" * Make sure that rasql is on the PATH first:\n"
                 '   $ source /etc/profile.d/rasdaman.sh')
        log.info(" * Then try some rasql queries using the rasql CLI, e.g:\n"
                 '   $ rasql -q \'select encode( mr, "png" ) from mr\' --out file')
        if profile.webapps_enabled:
            port = 8080
            if profile.webapps_deployment == "standalone":
                port = profile.petascope_standalone_port
            log.info(' * Try the WCS client in your browser at ' +
                'http://localhost:{}/rasdaman/ows\n\n'.format(str(port)))
        log.info('More information can be found at https://rasdaman.org. Have fun!')


def update():
    """
    Updates the installer
    """
    try:
        if ConfigManager.check_for_updates:
            log.info("Checking if installer needs to be updated...")
            if Updater().update():
                log.info("Installer was updated, restarting installer...")
                os.execv(__file__, sys.argv)
            log.info("Installer is at latest version.")
    except Exception as e:
        log.error("Installer could not be updated:")
        log.exception(str(e))


def install(profile):
    """
    Run the installation if the user accepts.
    """
    ChangeSeverity.update_default_severity(profile)
    set_severity_choice()
    print("")
    strategy = StrategyBuilder(profile).generate()
    log.title("Review the installation settings:")
    log.info(str(profile))
    if user_confirmed_change("Continue with installing rasdaman?", ChangeSeverity.CRITICAL):
        test_result = strategy.run()
        if test_result is not None and test_result.status == TestResultStatus.FAILURE:
            exit(1)
        bye_message(profile)


def main():
    """
    The main entry point in the program
    """
    profile = Profile()
    try:
        update()
        if len(sys.argv) > 1:
            try:
                profile.parse_profile(os.path.abspath(sys.argv[1]))
            except ProfileException as e:
                log.error(str(e))
                exit(1)
        else:
            log.error("Please specify an installation profile file.")
            exit(1)
        install(profile)
    except ExecutionError as e:
        log.error(("An error has occured while executing this command: {}." +
                   "Check the log at /tmp/rasdaman.install.log for more details.\n" +
                   "Preview of the error:\n" +
                   " Return code: {}\n" +
                   " Stderr: {}\n" +
                   " Stdout:{}").format(
                  e.command, e.return_code, e.stderr, e.stdout))
        exit(1)
    except Exception as e:
        log.error(
            "An unexpected error has occured. Please provide the file " +
            "/tmp/rasdaman.install.log and the below information to a developer:")
        log.exception(str(e))
        exit(1)


if __name__ == "__main__":
    main()
