#!/usr/bin/python
 # -*- coding: utf-8 -*-
 #
-# mailplate — apply templates to mail drafts.
+# mailplate — reformat mail drafts according to templates
 #
 # This script reformats mail drafts according to a given template. The
 # template may be specified on the command line, but mailplate can also use
 # TODO: if headers like From are absent from the mail, they should not be kept
 # but replaced with a default.
 #
-# Copyright © martin f. krafft <madduck@debian.org>
+# Copyright © martin f. krafft <madduck@madduck.net>
 # Released under the terms of the Artistic Licence 2.0
 #
 
+__name__ = 'mailplate'
+__description__ = 'reformat mail drafts according to templates'
+__version__ = '0.1'
+__author__ = 'martin f. krafft <madduck@madduck.net>'
+__copyright__ = 'Copyright © ' + __author__
+__licence__ = 'Artistic Licence 2.0'
+
 import email
 import os
 import posix
 ###
 
 def err(s):
-    sys.stderr.write(s + '\n')
+    sys.stderr.write('E: ' + s + '\n')
+
+def warn(s):
+    sys.stderr.write('W: ' + s + '\n')
+
+def info(s):
+    if not options.verbose: return
+    sys.stderr.write('I: ' + s + '\n')
 
 # obtain a regexp from a line, run it, return score/dict if matched
 def exec_regexp(line, rawmsg, name):
         else:
             return 0
     except OSError:
-        err("W: command '%s' (template '%s') failed to run." % (r, name))
+        warn("command '%s' (template '%s') failed to run." % (r, name))
         return 0
 
 def interpolate_helpers(s):
             out = proc.communicate()[0]
             s = s[:helper_begin] + out.strip() + s[helper_end+1:]
         except KeyError:
-            err('E: unknown helper: ' + helper)
+            err('unknown helper: ' + helper)
             sys.exit(posix.EX_DATAERR)
     return s
 
 headers = {}
 payload = None
 
+###
+### COMMAND LINE PARSING
+###
+
+parser = OptionParser()
+parser.prog = __name__
+parser.version = __version__
+parser.description = __description__
+parser.usage = '%prog [options] <message>'
+parser.add_option('-a', '--auto', dest='auto',
+        default=False, action='store_true',
+        help='turn on template auto-discovery')
+parser.add_option('-m', '--menu', dest='menu',
+        default=False, action='store_true',
+        help='choose from a list of templates (not yet implemented)')
+parser.add_option('-n', '--new', dest='new',
+        default=False, action='store_true',
+        help='create a new message')
+parser.add_option('-e', '--editor', dest='edit',
+        default=False, action='store_true',
+        help='spawn editor once template is applied')
+parser.add_option('-k', '--keep-unknown', dest='keep_unknown',
+        default=False, action='store_true',
+        help='preserve mail headers not specified in template')
+parser.add_option('-v', '--verbose', dest='verbose',
+        default=False, action='store_true',
+        help='write informational messages to stderr')
+parser.add_option('-d', '--debug', dest='debug',
+        default=False, action='store_true',
+        help='start a debugger after initialisation')
+parser.add_option('-V', '--version', dest='version',
+        default=False, action='store_true',
+        help='display version information')
+
+options, args = parser.parse_args()
+
+if options.version:
+    print __name__, __version__ + ' — ' + __description__
+    print
+    print 'Written by ' + __author__
+    print __copyright__
+    print 'Released under the ' + __licence__
+    sys.exit(posix.EX_OK)
+
 ###
 ### CONFIGURATION FILE PARSING
 ###
 MAILPLATEDIR = os.path.expanduser(MAILPLATEDIR)
 
 # defaults
-config = { 'default_template' : None
+config = { 'default_template' : 'default'
          , 'template_path' : TEMPLATEDIR
          }
 helpers = { 'get_quote' : 'fortune -s' }
 
 if not os.path.exists(CONFFILE):
     # conffile does not exist, let's create it with defaults.
+    options.verbose = True
 
     if not os.path.isdir(MAILPLATEDIR):
+        info('configuration directory not found, creating: ' + MAILPLATEDIR)
         os.mkdir(MAILPLATEDIR, 0700)
 
     if not os.path.isfile(CONFFILE):
+        info('creating a default configuration file: ' + CONFFILE)
         f = file(CONFFILE, 'w')
         f.write('# mailplate configuration\n[%s]\n' % SECTION_GENERAL)
         for kvpair in config.iteritems():
-            if kvpair[1] and len(kvpair[1]) > 0:
+            if len(kvpair[1]) > 0:
                 f.write('%s = %s\n' % kvpair)
 
         if len(helpers) > 0:
         f.close()
 
 if not os.access(CONFFILE, os.R_OK):
-    err('E: cannot read configuration file: %s' % CONFFILE)
+    err('cannot read configuration file: %s' % CONFFILE)
     sys.exit(posix.EX_OSFILE)
 
 # now parse
     try:
         config[key] = parser.get(SECTION_GENERAL, key)
     except ConfigParser.NoSectionError, ConfigParser.MissingSectionHeaderError:
-        err("E: no section '%s' in %s" % (SECTION_GENERAL, CONFFILE))
+        err("no section '%s' in %s" % (SECTION_GENERAL, CONFFILE))
         sys.exit(posix.EX_CONFIG)
     except ConfigParser.NoOptionError:
         continue
     except ConfigParser.DuplicateSectionError, ConfigParser.ParseError:
-        err('E: parse error on %s' % CONFFILE)
+        err('parse error on %s' % CONFFILE)
         sys.exit(posix.EX_CONFIG)
 
 # all HELPERS into the helpers dict
 
 TPATH = os.path.expanduser(config['template_path'])
 if not os.path.isdir(TPATH):
+    info('creating template directory: ' + TPATH)
     os.mkdir(TPATH, 0700)
 
-###
-### COMMAND LINE PARSING
-###
-
-parser = OptionParser()
-parser.usage = '%prog [options] <message>'
-parser.add_option('-a', '--auto', dest='auto',
-        default=False, action='store_true',
-        help='turn on template auto-discovery')
-parser.add_option('-m', '--menu', dest='menu',
-        default=False, action='store_true',
-        help='choose from a list of template')
-parser.add_option('-n', '--new', dest='new',
-        default=False, action='store_true',
-        help='create a new message')
-parser.add_option('-e', '--editor', dest='edit',
-        default=False, action='store_true',
-        help='spawn editor once template is applied')
-parser.add_option('-k', '--keep-unknown', dest='keep_unknown',
-        default=False, action='store_true',
-        help='preserve mail headers not specified in template')
-parser.add_option('-d', '--debug', dest='debug',
-        default=False, action='store_true',
-        help='start a debugger after initialisation')
-
-options, args = parser.parse_args()
+default_templname = config['default_template']
+if default_templname is not None:
+    default_templpath = os.path.join(TPATH, default_templname)
+    if not os.path.isfile(default_templpath):
+        info('creating the default template: ' + default_templpath)
+        f = file(default_templpath, 'w')
+        f.write('@KEEP_STD_HEADERS\n\n@KEEP_BODY\n')
+        f.close()
 
 if options.debug:
     import pdb
         # argument referenced an existing template
         templname = arg
     else:
-        err('E: unknown argument: %s' % arg)
+        err('unknown argument, and cannot find a template by this name: %s' % arg)
         sys.exit(posix.EX_USAGE)
 
 # sanity checks
 if options.auto and options.menu:
-    err('E: cannot combine --auto and --menu')
+    err('cannot combine --auto and --menu')
     sys.exit(posix.EX_USAGE)
 
 elif (options.auto or options.menu) and templname:
-    err('E: cannot specify a template with --auto or --menu')
+    err('cannot specify a template with --auto or --menu')
     sys.exit(posix.EX_USAGE)
 
 elif not templname and not (options.auto or options.menu):
-    err('E: no template specified')
-    sys.exit(posix.EX_USAGE)
+    if default_templname is not None:
+        templname = default_templname
+    else:
+        err('no template specified')
+        sys.exit(posix.EX_USAGE)
 
 elif options.menu:
-    err('E: --menu mode not yet implemented')
+    err('--menu mode not yet implemented')
     sys.exit(posix.EX_USAGE)
 
 ###
     rawmsg = ''.join(inf.readlines())
 
 if options.auto:
-    best_score = (0, config['default_template'], {})
+    best_score = (0, default_templname, {})
     for tf in os.listdir(TPATH):
         tp = os.path.join(TPATH, tf)
         if not os.path.isfile(tp) or not os.access(tp, os.R_OK): continue
     templname = best_score[1]
 
     if templname is None:
-        err('E: could not determine a template to use and no default is set')
+        err('could not determine a template to use and no default is set')
         sys.exit(posix.EX_CONFIG)
 
-    print >>sys.stderr, \
-            'I: Chose profile %s with score %d.' % (templname, best_score[0])
+    info('chose profile %s with score %d.' % (templname, best_score[0]))
     vars = best_score[2]
 
 # now read in the template
 templpath = os.path.join(TPATH, templname)
 
 if not os.path.isfile(templpath):
-    err('E: not a template: ' + templpath)
+    err('not a template: ' + templpath)
     sys.exit(posix.EX_OSFILE)
 
 elif not os.access(templpath, os.R_OK):
-    err('E: template ' + templpath + ' could not be read.')
+    err('template ' + templpath + ' could not be read.')
     sys.exit(posix.EX_OSFILE)
 
 templ = file(templpath, 'r', 1)
 if options.edit:
     # finally, spawn the editor, if we wrote into a file
     if outfname is None:
-        err('E: cannot use --edit without an output file.')
+        err('cannot use --edit without an output file.')
         sys.exit(posix.EX_USAGE)
 
     os.execlp('sensible-editor', 'sensible-editor', outfname)