#
# Copyright (C) 2008, 2009 Canonical Ltd
#
# This program 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.
#
"""Configuration tools for Loggerhead."""

import sys
import tempfile
from optparse import OptionParser

from breezy import config

_temporary_sql_dir = None

def _get_temporary_sql_dir():
    global _temporary_sql_dir
    if _temporary_sql_dir is None:
        _temporary_sql_dir = tempfile.mkdtemp(prefix='loggerhead-cache-')
    return _temporary_sql_dir

def command_line_parser():
    parser = OptionParser("%prog [options] <path>")
    parser.set_defaults(
        user_dirs=False,
        show_version=False,
        log_folder=None,
        use_cdn=False,
        sql_dir=None,
        allow_writes=False,
        export_tarballs=True,
        )
    parser.add_option("--user-dirs", action="store_true",
                      help="Serve user directories as ~user.")
    parser.add_option("--trunk-dir", metavar="DIR",
                      help="The directory that contains the trunk branches.")
    parser.add_option("--port", dest="user_port",
                      help=("Port Loggerhead should listen on "
                            "(defaults to 8080)."))
    parser.add_option("--host", dest="user_host",
                      help="Host Loggerhead should listen on.")
    parser.add_option("--protocol", dest="protocol",
                      help=("Protocol to use: http, scgi, fcgi, ajp"
                           "(defaults to http)."))
    parser.add_option("--log-level", default=None, action='callback',
                      callback=_optparse_level_to_int_level,
                      type="string",
                      help="Set the verbosity of logging. Can either"
                           " be set to a numeric or string"
                           " (eg, 10=debug, 30=warning)")
    parser.add_option("--memory-profile", action="store_true",
                      help="Profile the memory usage using Dozer.")
    parser.add_option("--prefix", dest="user_prefix",
                      help="Specify host prefix.")
    parser.add_option("--profile", action="store_true",
                      help="Generate callgrind profile data to "
                        "%d-stats.callgrind on each request.")
    parser.add_option("--reload", action="store_true",
                      help="Restarts the application when changing python"
                           " files. Only used for development purposes.")
    parser.add_option("--log-folder",
                      help="The directory to place log files in.")
    parser.add_option("--version", action="store_true", dest="show_version",
                      help="Print the software version and exit")
    parser.add_option("--use-cdn", action="store_true", dest="use_cdn",
                      help="Serve jQuery from Google's CDN")
    parser.add_option("--cache-dir", dest="sql_dir",
                      help="The directory to place the SQL cache in")
    parser.add_option("--allow-writes", action="store_true",
                      help="Allow writing to the Bazaar server.")
    parser.add_option("--export-tarballs", action="store_true",
                      help="Allow exporting revisions to tarballs.")
    return parser


_log_levels = {
    'debug': 10,
    'info': 20,
    'warning': 30,
    'error': 40,
    'critical': 50,
}

def _optparse_level_to_int_level(option, opt_str, value, parser):
    parser.values.log_level = _level_to_int_level(value)


def _level_to_int_level(value):
    """Convert a string level to an integer value."""
    if value is None:
        return None
    try:
        return int(value)
    except ValueError:
        pass
    return _log_levels[value.lower()]


class LoggerheadConfig(object):
    """A configuration object."""

    def __init__(self, argv=None):
        if argv is None:
            argv = sys.argv[1:]
        self._parser = command_line_parser()
        self._options, self._args = self._parser.parse_args(argv)

        sql_dir = self.get_option('sql_dir')
        if sql_dir is None:
            sql_dir = _get_temporary_sql_dir()
        self.SQL_DIR = sql_dir

    def get_option(self, option):
        """Get the value for the config option, either
        from ~/.config/breezy/breezy.conf or from the command line.
        All loggerhead-specific settings start with 'http_'
        """
        global_config = config.GlobalConfig().get_user_option('http_'+option)
        cmd_config = getattr(self._options, option)
        if global_config is not None and (
            cmd_config is None or cmd_config is False):
            return global_config
        else:
            return cmd_config

    def get_log_level(self):
        opt = self.get_option('log_level')
        return _level_to_int_level(opt)

    def get_arg(self, index):
        """Get an arg from the arg list."""
        return self._args[index]

    def print_help(self):
        """Wrapper around OptionParser.print_help."""
        return self._parser.print_help()

    @property
    def arg_count(self):
        """Return the number of args from the option parser."""
        return len(self._args)
