#! /usr/bin/python
"""
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 sys, os, imp, optparse
from os import path
from textwrap import dedent as trim

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

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

def create_default_config(fn): 
   f = open(fn, 'w')
   print >> f, trim("""\
   nick = "phenny"
   host = "irc.example.net"
   # password = "password"
   channels = ["#example", "#test"]
   owner = "your-nick"

   # people allowed to use admin.py functions
   admins = [owner, "other-nick"]

   # for available modules see /usr/share/python-support/phenny/phenny/modules

   # exclude modules
   exclude = ["admin"]

   # enable specific modules, trumps exclude
   # enable = []

   # extra modules to load by filename
   # extra = ["~/.phenny/example-a.py", "~/.phenny/example-b.py"]

   # limit modules in specific channels
   # limit = {"#channel": ["module-a", "module-b"]}
   """)
   f.close()

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

   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 check_dotdir(): 
   if not os.path.isdir(dotdir): 
      create_dotdir(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 >> sys.stderr, "Error: Couldn't find a config file!"
   print >> sys.stderr, 'What happened to ~/.phenny/default.py?'
   sys.exit(1)

def main(argv=None): 
   # Step One: Check Dependencies

   check_python_version() # require python2.4 or later

   # Step Two: Parse The Command Line

   def display_error(message):
      print >> sys.stderr, message
      print >> sys.stderr
      print >> sys.stderr, "Try `phenny -h' for more information."
      sys.exit(1)

   verbose = False
   config = None
   for key, arg in enumerate(sys.argv[1:]):
       if arg == "-h" or arg == "--help":
           print """Usage: phenny [OPTION]...

Options:

  -h, --help           display a short help message and exit
  -V, --version        display version information and exit
  -v, --verbose        display extended startup information
  -c, --config CONFIG  use CONFIG as the configuration file or directory

Examples:

To start using Phenny run the phenny command:

  phenny

Edit the default files created in your home directory:

  sensible-editor ~/.phenny/default.py

You can now start Phenny and try out your configuration:

  phenny

If you want to start Phenny as a background process you might run:

  nohup phenny 2> ~/.phenny/log.txt &

Report bugs using the `reportbug phenny' command."""
           sys.exit(0)
       elif arg == "-V" or arg == "--version":
           print """phenny - Phenny

Copyright 2008, Sean B. Palmer <http://inamidst.com/sbp/>

Licensed under the Eiffel Forum License 2.

Written by Sean B. Palmer <http://inamidst.com/sbp/>."""
           sys.exit(0)
       elif arg == "-v" or arg == "--verbose":
          verbose = True
       elif arg == "-c" or arg == "--config":
          config = sys.argv[key + 2]
          if not path.exists(config):
             display_error("The file or directory does not exist: %s" % config)
       elif arg.startswith("-"):
          display_error("Unknown option: %s" % arg)
       else:
          display_error("Unknown argument: %s" % arg)

   check_dotdir() # require ~/.phenny, or make it and exit

   # Step Three: Load The Configurations

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

      if not hasattr(module, 'prefix'): 
         module.prefix = r'\.'

      if not hasattr(module, 'name'): 
         module.name = 'Phenny Palmersbot, http://inamidst.com/phenny/'

      if not hasattr(module, 'port'): 
         module.port = 6667

      if module.host == 'irc.example.net': 
         error = ('Error: you must edit the config file first!\n' + 
                  "You're currently using %s" % module.filename)
         print >> sys.stderr, error
         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 >> sys.stderr, "Error: Couldn't find phenny to import"
         sys.exit(1)

   # Step Five: Initialise And Run The Phennies

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

if __name__ == '__main__': 
   main()
