#!/usr/bin/env python3
"""
phenny - An IRC Bot
Copyright 2008, Sean B. Palmer, inamidst.com
Licensed under the Eiffel Forum License 2.

http://inamidst.com/phenny/

Note: DO NOT EDIT THIS FILE.
Run ./phenny, then edit ~/.phenny/default.py
Then run ./phenny again
"""

import argparse
import os
import sys
from importlib.machinery import SourceFileLoader
from textwrap import dedent as trim

dotdir = os.path.expanduser('~/.phenny')


def check_python_version():
    if sys.version_info < (3, 4):
        error = 'Error: Requires Python 3.4 or later, from www.python.org'
        print(error, file=sys.stderr)
        sys.exit(1)


def create_default_config(fn):
    f = open(fn, 'w')
    print(trim("""\
    nick = 'phenny'
    host = 'irc.example.net'
    port = 6667
    ssl = False
    ipv6 = False
    channels = ['#example', '#test']
    owner = 'yournickname'

    # password is the NickServ password, serverpass is the server password
    # password = 'example'
    # serverpass = 'serverpass'

    # linx-enabled features (.linx, .lnx)
    # leave the api key blank to not use them and be sure to add the 'linx' module to the ignore list.
    linx_api_key = ""

    # These are people who will be able to use admin.py's functions...
    admins = [owner, 'someoneyoutrust']
    # But admin.py is disabled by default, as follows:
    exclude = ['admin', 'linx', 'foodforus']

    ignore = ['']

    # If you want to enumerate a list of modules rather than disabling
    # some, use "enable = ['example']", which takes precedent over exclude
    #
    # enable = []

    # Directories to load user modules from
    # e.g. /path/to/my/modules
    extra = []

    # Services to load: maps channel names to white or black lists
    external = {
        '#liberal': ['!'], # allow all
        '#conservative': [], # allow none
        '*': ['!'] # default whitelist, allow all
    }

    # EOF
    """), file=f)
    f.close()


def create_default_config_file(dotdir):
    print('Creating a default config file at ~/.phenny/default.py...')
    default = os.path.join(dotdir, 'default.py')
    create_default_config(default)

    print('Done; now you can edit default.py, and run phenny! Enjoy.')
    sys.exit(0)


def create_dotdir(dotdir):
    print('Creating a config directory at ~/.phenny...')
    try:
        os.mkdir(dotdir)
    except Exception as e:
        print('There was a problem creating %s:' % dotdir, file=sys.stderr)
        print(e.__class__, str(e), file=sys.stderr)
        print('Please fix this and then run phenny again.', file=sys.stderr)
        sys.exit(1)

    create_default_config_file(dotdir)


def check_dotdir():
    default = os.path.join(dotdir, 'default.py')

    if not os.path.isdir(dotdir):
        create_dotdir(dotdir)
    elif not os.path.isfile(default):
        create_default_config_file(dotdir)


def config_names(config):
    config = config or 'default'

    def files(d):
        names = os.listdir(d)
        return list(os.path.join(d, fn) for fn in names if fn.endswith('.py'))

    here = os.path.join('.', config)
    if os.path.isfile(here):
        return [here]
    if os.path.isfile(here + '.py'):
        return [here + '.py']
    if os.path.isdir(here):
        return files(here)

    there = os.path.join(dotdir, config)
    if os.path.isfile(there):
        return [there]
    if os.path.isfile(there + '.py'):
        return [there + '.py']
    if os.path.isdir(there):
        return files(there)

    print("Error: Couldn't find a config file!", file=sys.stderr)
    print('What happened to ~/.phenny/default.py?', file=sys.stderr)
    sys.exit(1)


def main(argv=None):
    # Step One: Parse The Command Line

    parser = argparse.ArgumentParser(description="A Python IRC bot.")
    parser.add_argument('-c', '--config', metavar='fn',
                        help='use this configuration file or directory')
    args = parser.parse_args(argv)

    # Step Two: Check Dependencies

    check_python_version()
    if not args.config:
        check_dotdir()  # require ~/.phenny, or make it and exit

    # Step Three: Load The Configurations

    config_modules = []
    for config_name in config_names(args.config):
        name = os.path.basename(config_name).split('.')[0] + '_config'
        module = SourceFileLoader(name, config_name).load_module()
        module.filename = config_name

        defaults = {
            'prefix': r'\.',
            'name': 'Phenny Palmersbot, http://inamidst.com/phenny/',
            'port': 6667,
            'ssl': False,
            'ca_certs': None,
            'ssl_cert': None,
            'ssl_key': None,
            'ipv6': False,
            'password': None,
        }

        for key, value in defaults.items():
            if not hasattr(module, key):
                setattr(module, key, value)

        if module.host == 'irc.example.net':
            error = ('Error: you must edit the config file first!\n' +
                     "You're currently using %s" % module.filename)
            print(error, file=sys.stderr)
            sys.exit(1)

        config_modules.append(module)

    # Step Four: Load Phenny

    try:
        from __init__ import run
    except ImportError:
        try:
            from phenny import run
        except ImportError:
            print("Error: Couldn't find phenny to import", file=sys.stderr)
            sys.exit(1)

    # Step Five: Initialise And Run The Phennies

    # @@ ignore SIGHUP
    for config_module in config_modules:
        run(config_module)  # @@ thread this


if __name__ == '__main__':
    main()