#!/usr/bin/python
# -*- coding: UTF-8 -*-

###############################################################################
#                                                                             #
# Bazaar Browser - A simple web application for browsing Bazaar repository    #
#                                                                             #
# Copyright (C) 2011-2012  Fabien LOISON <http://www.flogisoft.com/>          #
# Copyright (C) 2012  Mickaël FORTUNATO <mickael.fortunato AT supinfo DOT com>#
#                                                                             #
# This program is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU Affero General Public License as published by #
# the Free Software Foundation, either version 3 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 Affero General Public License for more details.                         #
#                                                                             #
# You should have received a copy of the GNU Affero General Public License    #
# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
#                                                                             #
###############################################################################


"""The configuration of Bazaar Browser."""


import platform
from re import sub
from os.path import isfile, join
from ConfigParser import SafeConfigParser


def _get_config_path():
    """Determine the configuration file's path.
    Returns:
        The configuration file's path.
    """
    # Relative path for every OS (useful for dev)
    if isfile(join(".", "bzrbrowser.conf")):
        return join(".", "bzrbrowser.conf")       # ./bzrbrowser.conf
    # Path for GNU/Linux and Mac OS
    if platform.system().lower() in ["linux", "darwin"]:
        return "/etc/bzrbrowser.conf"             # /etc/bzrbrowser.conf


class Config(dict):
    """The Bazaar Borwser configuration.
    Options and default values:
        * server/debug = False
          Enable or Disable the debugging log and console.
          The debugging must be disable on a production environment
          (security risk).

        * server/host = "127.0.0.1"
          The built-in server will respond only to the given host.
          Set the value to 0.0.0.0 for responding to all hosts
          (not recommended).

        * server/port = 5000
          The built-in server's port.

        * repository/path = "/var/repository"
          The directory where branches are stored.

        * repository/pushurl = "sftp://USER@host/repository/"
          The base URL of the writable access to the repository (sftp, ftp).

        * cache/path = "/tmp"
          The directory used to stored archives generated by the exportation's
          function.

        * branch/readmefiles = ["README", "readme", "Readme", "ReadMe",
                "README.TXT", "README.txt", "Readme.txt", "Readme.TXT",
                "ReadMe.txt"]
          A list of filename that can contain information about the branch or
          the project (typically a README file).
    """

    def __init__(self):
        """The constructor."""
        # Default config
        self['server/debug'] = False
        self['server/host'] = "127.0.0.1"
        self['server/port'] = 5000
        self['repository/path'] = "/var/repository"
        self['repository/pushurl'] = "sftp://USER@host/repository/"
        self['cache/path'] = "/tmp"
        self['branch/readmefiles'] = ["README", "readme", "Readme", "ReadMe",
                "README.TXT", "README.txt", "Readme.txt", "Readme.TXT",
                "ReadMe.txt"]
        # Load from file
        if isfile(_get_config_path()):
            self._load_from_file(_get_config_path())

    def _load_from_file(self, filepath):
        """Read the configuration from the given file.
        Args:
            filepath -- The path of the configuration file (file must exists)
        """
        # Translation dict (for casting variables)
        cast = {int: int,
                str: str,
                bool: lambda x: bool(int(x)),
                list: lambda x: sub(r"\s*,\s*", ",", x).split(",")}
        # Parse the config file
        config_parser = SafeConfigParser()
        config_parser.read(filepath)
        for section in config_parser.sections():
            for key, value in config_parser.items(section):
                ckey = '%s/%s' % (section.lower(), key.lower())
                # Update the config
                if ckey in self:
                    self[ckey] = cast[type(self[ckey])](value)


config = Config()
