#!/usr/bin/env python
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
"""Initial configuration for Bloodhound"""

import os
import pkg_resources
import shutil
import sys
from createdigest import htdigest_create
from getpass import getpass
from optparse import OptionParser

try:
    from trac.admin.console import TracAdmin
    from trac.config import Configuration
    from trac.util import translation
    from trac.util.translation import _, get_negotiated_locale, has_babel
except ImportError, e:
    print("Requirements must be installed before running "
          "bloodhound_setup.py.\n"
          "You can install them with the following command:\n"
          "   pip install -r requirements.txt\n")
    sys.exit(1)

try:
    import psycopg2
except ImportError:
    psycopg2 = None

try:
    import MySQLdb as mysqldb
except ImportError:
    mysqldb = None

LANG = os.environ.get('LANG')

MAXBACKUPNUMBER = 64  # Max attempts to create backup file

SUPPORTED_DBTYPES = ('sqlite', 'postgres', 'mysql')
DEFAULT_DB_USER = 'bloodhound'
DEFAULT_DB_NAME = 'bloodhound'
DEFAULT_ADMIN_USER = 'admin'

BH_PROJECT_SITE = 'https://issues.apache.org/bloodhound/'
BASE_CONFIG = {'components': {'bhtheme.*': 'enabled',
                              'bhdashboard.*': 'enabled',
                              'multiproduct.*': 'enabled',
                              'permredirect.*': 'enabled',
                              'themeengine.api.*': 'enabled',
                              'themeengine.web_ui.*': 'enabled',
                              'bhsearch.*': 'enabled',
                              'bhrelations.*': 'enabled',
                              'trac.ticket.web_ui.ticketmodule': 'disabled',
                              'trac.ticket.report.reportmodule': 'disabled',
                              },
               'header_logo': {'src': '',},
               'mainnav': {'roadmap': 'disabled',
                           'search': 'disabled',
                           'timeline': 'disabled',},
               'metanav': {'about': 'disabled',},
               'theme': {'theme': 'bloodhound',},
               'trac': {'mainnav': ','.join(['dashboard', 'wiki', 'browser',
                                             'tickets', 'newticket', 'timeline',
                                             'roadmap', 'search']),
                        'environment_factory': '',
                        'request_factory': '',},
               'project': {'footer': ('Get involved with '
                                      '<a href="%(site)s">Apache Bloodhound</a>'
                                      % {'site': BH_PROJECT_SITE,}),},
               'labels': {'application_short': 'Bloodhound',
                          'application_full': 'Apache Bloodhound',
                          'footer_left_prefix': '',
                          'footer_left_postfix': '',
                          'footer_right': ''},
               'bhsearch': {'is_default': 'true', 'enable_redirect': 'true'},
}

ACCOUNTS_CONFIG = {'account-manager': {'account_changes_notify_addresses' : '',
                                       'authentication_url' : '',
                                       'db_htdigest_realm' : '',
                                       'force_passwd_change' :'true',
                                       'hash_method' : 'HtDigestHashMethod',
                                       'htdigest_file' : '',
                                       'htdigest_realm' : '',
                                       'htpasswd_file' : '',
                                       'htpasswd_hash_type' : 'crypt',
                                       'password_store' : 'HtDigestStore',
                                       'persistent_sessions' : 'False',
                                       'refresh_passwd' : 'False',
                                       'user_lock_max_time' : '0',
                                       'verify_email' : 'True',
                                       },
                   'components': {'acct_mgr.admin.*' : 'enabled',
                                  'acct_mgr.api.accountmanager' : 'enabled',
                                  'acct_mgr.guard.accountguard' : 'enabled',
                                  'acct_mgr.htfile.htdigeststore' : 'enabled',
                                  'acct_mgr.macros.*': 'enabled',
                                  'acct_mgr.web_ui.accountmodule' : 'enabled',
                                  'acct_mgr.web_ui.loginmodule' : 'enabled',
                                  'trac.web.auth.loginmodule' : 'disabled',
                                  },
                   }

class BloodhoundSetup(object):
    """Creates a Bloodhound environment"""

    def __init__(self, opts):
        if isinstance(opts, dict):
            options = dict(opts)
        else:
            options = vars(opts)
        self.options = options

        if 'project' not in options:
            options['project'] = 'main'
        if 'envsdir' not in options:
            options['envsdir'] = os.path.join('bloodhound',
                                              'environments')

        # Flags used when running the functional test suite
        self.apply_bhwiki_upgrades = True

    def _generate_db_str(self, options):
        """Builds an appropriate db string for trac-admin for sqlite and
        postgres options. Also allows for a user to provide their own db
        string to allow database initialisation beyond these."""
        dbdata = {'type': options.get('dbtype', 'sqlite'),
                  'user': options.get('dbuser'),
                  'pass': options.get('dbpass'),
                  'host': options.get('dbhost', 'localhost'),
                  'port': options.get('dbport'),
                  'name': options.get('dbname', 'bloodhound'),
                  }

        db = options.get('dbstring')
        if db is None:
            if dbdata['type'] in ('postgres', 'mysql') \
                    and dbdata['user'] is not None \
                    and dbdata['pass'] is not None:
                if dbdata['port'] is not None:
                    db = '%(type)s://%(user)s:%(pass)s@%(host)s:%(port)s/%(name)s'
                else:  # no port specified = default port
                    db = '%(type)s://%(user)s:%(pass)s@%(host)s/%(name)s'
            else:
                db = '%%(type)s:%s' % os.path.join('db', '%(name)s.db')
        return db % dbdata

    def setup(self, **kwargs):
        """Do the setup. A kwargs dictionary may be passed to override base
        options, potentially allowing for multiple environment creation."""

        if has_babel:
            import babel
            try:
                locale = get_negotiated_locale([LANG])
                locale = locale or babel.Locale.default()
            except babel.UnknownLocaleError:
                pass
            translation.activate(locale)

        options = dict(self.options)
        options.update(kwargs)
        if psycopg2 is None and options.get('dbtype') == 'postgres':
            print "psycopg2 needs to be installed to initialise a postgresql db"
            return False
        elif mysqldb is None and options.get('dbtype') == 'mysql':
            print "MySQLdb needs to be installed to initialise a mysql db"
            return False

        environments_path = options['envsdir']
        if not os.path.exists(environments_path):
            os.makedirs(environments_path)

        new_env =  os.path.join(environments_path, options['project'])
        tracini = os.path.abspath(os.path.join(new_env, 'conf', 'trac.ini'))
        baseini = os.path.abspath(os.path.join(new_env, 'conf', 'base.ini'))
        options['inherit'] = '"' + baseini + '"'

        options['db'] = self._generate_db_str(options)
        if 'repo_type' not in options or options['repo_type'] is None:
            options['repo_type'] = ''
        if 'repo_path' not in options or options['repo_path'] is None:
            options['repo_path'] = ''
        if (len(options['repo_type']) > 0) ^ (len(options['repo_path']) > 0):
            print "Error: Specifying a repository requires both the "\
                  "repository-type and the repository-path options."
            return False

        custom_prefix = 'default_product_prefix'
        if custom_prefix in options and options[custom_prefix]:
            default_product_prefix = options[custom_prefix]
        else:
            default_product_prefix = '@'

        digestfile = os.path.abspath(os.path.join(new_env,
                                                  options['digestfile']))
        realm =  options['realm']
        adminuser = options['adminuser']
        adminpass = options['adminpass']

        # create base options:
        accounts_config = dict(ACCOUNTS_CONFIG)
        accounts_config['account-manager']['htdigest_file'] = digestfile
        accounts_config['account-manager']['htdigest_realm'] = realm

        trac = TracAdmin(os.path.abspath(new_env))
        if not trac.env_check():
            try:
                rv = trac.do_initenv('%(project)s %(db)s '
                                     '%(repo_type)s %(repo_path)s '
                                     '--inherit=%(inherit)s '
                                     '--nowiki'
                                     % options)
                if rv == 2:
                    raise SystemExit
            except SystemExit:
                print ("Error: Unable to initialise the environment.")
                return False
        else:
            print ("Warning: Environment already exists at %s." % new_env)
            self.writeconfig(tracini, [{'inherit': {'file': baseini},},])

        base_config = dict(BASE_CONFIG)
        environment_factory_path = os.path.abspath(
                                      os.path.normpath(
                                          os.path.join(options['sourcedir'],
                                                               'bloodhound_multiproduct/multiproduct/hooks.py')))
        request_factory_path = os.path.abspath(
                                   os.path.normpath(
                                       os.path.join(options['sourcedir'],
                                                            'bloodhound_multiproduct/multiproduct/hooks.py')))
        base_config['trac']['environment_factory'] = environment_factory_path
        base_config['trac']['request_factory'] = request_factory_path
        if default_product_prefix != '@':
            base_config['multiproduct'] = dict(
                default_product_prefix=default_product_prefix
            )

        self.writeconfig(baseini, [base_config, accounts_config])

        if os.path.exists(digestfile):
            backupfile(digestfile)
        htdigest_create(digestfile, adminuser, realm, adminpass)

        print "Adding TRAC_ADMIN permissions to the admin user %s" % adminuser
        trac.onecmd('permission add %s TRAC_ADMIN' % adminuser)

        # get fresh TracAdmin instance (original does not know about base.ini)
        bloodhound = TracAdmin(os.path.abspath(new_env))

        # final upgrade
        print "Running upgrades"
        bloodhound.onecmd('upgrade')
        pages = []
        pages.append(pkg_resources.resource_filename('bhdashboard',
                                                 'default-pages'))
        pages.append(pkg_resources.resource_filename('bhsearch',
                                                 'default-pages'))
        bloodhound.onecmd('wiki load %s' % " ".join(pages))

        print "Running wiki upgrades"
        bloodhound.onecmd('wiki upgrade')

        if self.apply_bhwiki_upgrades:
            print "Running wiki Bloodhound upgrades"
            bloodhound.onecmd('wiki bh-upgrade')
        else:
            print "Skipping Bloodhound wiki upgrades"

        print "Loading default product wiki"
        bloodhound.onecmd('product admin %s wiki load %s' %
                          (default_product_prefix,
                           " ".join(pages)))

        print "Running default product wiki upgrades"
        bloodhound.onecmd('product admin %s wiki upgrade' %
                          default_product_prefix)

        if self.apply_bhwiki_upgrades:
            print "Running default product Bloodhound wiki upgrades"
            bloodhound.onecmd('product admin %s wiki bh-upgrade' %
                              default_product_prefix)
        else:
            print "Skipping default product Bloodhound wiki upgrades"

        print """
You can now start Bloodhound by running:

  tracd --port=8000 %s

And point your browser at http://localhost:8000/%s
""" % (os.path.abspath(new_env), options['project'])
        return True

    def writeconfig(self, filepath, dicts=[]):
        """Writes or updates a config file. A list of dictionaries is used so
        that options for different aspects of the configuration can be kept
        separate while being able to update the same sections. Note that the
        result is order dependent where two dictionaries update the same
        option.
        """
        config = Configuration(filepath)
        file_changed = False
        for data in dicts:
            for section, options in data.iteritems():
                for key, value in options.iteritems():
                    if config.get(section, key, None) != value:
                        # This should be expected to generate a false positive
                        # when two dictionaries update the same option
                        file_changed = True
                    config.set(section, key, value)
        if file_changed:
            if os.path.exists(filepath):
                backupfile(filepath)
            config.save()

def backupfile(filepath):
    """Very basic backup routine"""
    print "Warning: Updating %s." % filepath
    backuppath = None
    if not os.path.exists(filepath + '_bak'):
        backuppath = filepath + '_bak'
    else:
        backuptemplate = filepath + '_bak_%d'
        for i in xrange(MAXBACKUPNUMBER):
            if not os.path.exists(backuptemplate % i):
                backuppath = backuptemplate % i
                break
    if backuppath is not None:
        shutil.copyfile(filepath, backuppath)
        print "Backup created at %s." % backuppath
    else:
        print "No backup created (too many other backups found)"
    return backuppath

def handle_options():
    """Parses the command line, with basic prompting for choices where options
    are not specified."""
    parser = OptionParser()

    # Base Trac Options
    parser.add_option('--project', dest='project',
                      help='Set the top project name', default='main')
    parser.add_option('--source_directory', dest='sourcedir',
                      help='Specify root source code directory',
                      default=os.path.normpath(os.path.join(os.getcwd(), '../'))),
    parser.add_option('--environments_directory', dest='envsdir',
                      help='Set the directory to contain environments',
                      default=os.path.join('bloodhound', 'environments'))
    parser.add_option('-d', '--database-type', dest='dbtype',
                      help="Specify as either 'sqlite', 'postgres' or 'mysql'",
                      default='')
    parser.add_option('--database-string', dest='dbstring',
                      help=('Advanced: provide a custom database string, '
                            'overriding other database options'),
                      default=None)
    parser.add_option('--database-name', dest='dbname',
                      help='Specify the database name',
                      default='bloodhound')
    parser.add_option('-u', '--user', dest='dbuser',
                      help='Specify the db user (required for postgres and mysql)',
                      default='')
    parser.add_option('-p', '--password', dest='dbpass',
                      help='Specify the db password (required for postgres and mysql)')
    parser.add_option('--database-host', dest='dbhost',
                      help='Specify the database host (optional for postgres and mysql)',
                      default='localhost')
    parser.add_option('--database-port', dest='dbport',
                      help='Specify the database port (optional for postgres and mysql)',
                      default='5432')

    # Account Manager Options
    parser.add_option('--admin-password', dest='adminpass',
                      help='create an admin user in an htdigest file')
    parser.add_option('--digest-realm', dest='realm', default='bloodhound',
                      help='authentication realm for htdigest file')
    parser.add_option('--admin-user', dest='adminuser', default='',
                      help='admin user name for htdigest file')
    parser.add_option('--digest-file', dest='digestfile',
                      default='bloodhound.htdigest',
                      help='filename for the htdigest file')

    # Repository Options
    parser.add_option('--repository-type', dest='repo_type',
                      help='specify the repository type - ')
    parser.add_option('--repository-path', dest='repo_path',
                      help='specify the repository type')

    # Multiproduct options
    parser.add_option('--default-product-prefix', dest='default_product_prefix',
                      help='Specify prefix for default product (defaults to @')

    (options, args) = parser.parse_args()
    if args:
        print "Unprocessed options/arguments: ", args

    def ask_question(question, default=None):
        """Basic question asking functionality"""
        if default:
            answer = raw_input(question % default)
        else:
            answer = raw_input(question)
        return answer if answer else default

    def ask_password(user):
        """Asks for a password to be provided for setting purposes"""
        attempts = 3
        for attempt in range(attempts):
            if attempt > 0:
                print "Passwords empty or did not match. Please try again",
                print "(attempt %d/%d)""" % (attempt+1, attempts)
            password1 = getpass('Enter a new password for "%s": ' % user)
            password2 = getpass('Please reenter the password: ')
            if password1 and password1 == password2:
                return password1
        print "Passwords did not match. Quiting."
        sys.exit(1)

    if options.dbtype.lower() not in SUPPORTED_DBTYPES:
        answer = ask_question("""
This installer is able to install Apache Bloodhound with either SQLite,
PostgreSQL or MySQL databases. SQLite is an easier option for installing
Bloodhound as SQLite support is built into Python and requires no special
permissions to run. However, PostgreSQL and MySQL are generally expected to
be more robust for production use.
What type of database do you want to instant to (%s)?
[%%s]: """ % '/'.join(SUPPORTED_DBTYPES), default='sqlite')
        answer = answer.lower()
        if answer in SUPPORTED_DBTYPES:
            options.dbtype = answer
        else:
            print "Unrecognized dbtype \"%s\". Quiting." % answer
            sys.exit(1)
    else:
        options.dbtype = options.dbtype.lower()

    if options.dbtype in ('postgres','mysql'):
        if not options.dbuser:
            options.dbuser = ask_question("""
For PostgreSQL/MySQL you need to have PostgreSQL/MySQL installed and you need
to have created a database user to connect to the database with. Setting this 
up may require admin access rights to the server.
DB user name [%s]: """, DEFAULT_DB_USER)

        if not options.dbpass:
            options.dbpass = ask_password(options.dbuser)

        if not options.dbname:
            options.dbname = ask_question("""
For PostgreSQL/MySQL setup, you need to specify a database that you have
created for Bloodhound to use. This installer currently assumes that this
database will be empty. DB name [%s]: """, DEFAULT_DB_NAME)
    if not options.adminuser:
        options.adminuser = ask_question("""
Please supply a username for the admin user [%s]: """, DEFAULT_ADMIN_USER)
    if not options.adminpass:
        options.adminpass = ask_password(options.adminuser)

    return options


if __name__ == '__main__':
    options = handle_options()
    bsetup = BloodhoundSetup(options)
    bsetup.setup()
