'''This script allows to generate a product from a Appy application.'''

# ------------------------------------------------------------------------------
import sys, os.path
from optparse import OptionParser
from appy.gen.generator import GeneratorError
from appy.shared.utils import LinesCounter

# ------------------------------------------------------------------------------
ERROR_CODE = 1
VALID_PRODUCT_TYPES = ('plone25', 'odt')
APP_NOT_FOUND = 'Application not found at %s.'
WRONG_NG_OF_ARGS = 'Wrong number of arguments.'
WRONG_OUTPUT_FOLDER = 'Output folder not found. Please create it first.'
PRODUCT_TYPE_ERROR = 'Wrong product type. Product type may be one of the ' \
                     'following: %s' % str(VALID_PRODUCT_TYPES)
C_OPTION = 'Removes from i18n files all labels that are not automatically ' \
           'generated from your gen-application. It can be useful during ' \
           'development, when you do lots of name changes (classes, ' \
           'attributes, states, transitions, etc): in this case, the Appy ' \
           'i18n label generation machinery produces lots of labels that ' \
           'then become obsolete.'
S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \
           'generated i18n files, you will find first all labels ' \
           'that are automatically generated by appy.gen, in some logical ' \
           'order (ie: field-related labels appear together, in the order ' \
           'they are declared in the gen-class). Then, if you have added ' \
           'labels manually, they will appear afterwards. Sorting labels ' \
           'may not be desired under development. Indeed, when no sorting ' \
           'occurs, every time you add or modify a field, class, state, etc, ' \
           'newly generated labels will all appear together at the end of ' \
           'the file; so it will be easy to translate them all. When sorting ' \
           'occurs, those elements may be spread at different places in the ' \
           'i18n file. When the development is finished, it may be a good ' \
           'idea to sort the labels to get a clean and logically ordered ' \
           'set of translation files.'

class GeneratorScript:
    '''usage: %prog [options] app productType outputFolder

       "app"          is the path to your Appy application, which may be a
                      Python module (= a file than ends with .py) or a Python
                      package (= a folder containing a file named __init__.py).
                      Your app may reside anywhere (but it needs to be
                      accessible by the underlying application server, ie Zope),
                      excepted within the generated product. Typically, if you
                      generate a Plone product, it may reside within
                      <yourZopeInstance>/lib/python, but not within the
                      generated product (typically stored in
                      <yourZopeInstance>/Products).
       "productType"  is the kind of product you want to generate
                      (currently, only "plone25" and 'odt' are supported;
                      in the near future, the "plone25" target will also produce
                      Plone 3-compliant code that will still work with
                      Plone 2.5).
       "outputFolder" is the folder where the product will be generated.
                      For example, if you specify /my/output/folder for your
                      application /home/gde/MyApp.py, this script will create
                      a folder /my/output/folder/MyApp and put in it the
                      generated product.

       Example: generating a Plone product
       -----------------------------------
       In your Zope instance named myZopeInstance, create a folder
       "myZopeInstance/lib/python/MyApp". Create into it your Appy application
       (we suppose here that it is a Python package, containing a __init__.py
       file and other files). Then, chdir into this folder and type
       "python <appyPath>/gen/generator.py . plone25 ../../../Products" and the
       product will be generated in myZopeInstance/Products/MyApp.
       "python" must refer to a Python interpreter that knows package appy.'''

    def generateProduct(self, options, application, productType, outputFolder):
        exec 'from appy.gen.%s.generator import Generator' % productType
        Generator(application, outputFolder, options).run()

    def manageArgs(self, parser, options, args):
        # Check number of args
        if len(args) != 3:
            print WRONG_NG_OF_ARGS
            parser.print_help()
            sys.exit(ERROR_CODE)
        # Check productType
        if args[1] not in VALID_PRODUCT_TYPES:
            print PRODUCT_TYPE_ERROR
            sys.exit(ERROR_CODE)
        # Check existence of application
        if not os.path.exists(args[0]):
            print APP_NOT_FOUND % args[0]
            sys.exit(ERROR_CODE)
        # Check existence of outputFolder basic type
        if not os.path.exists(args[2]):
            print WRONG_OUTPUT_FOLDER
            sys.exit(ERROR_CODE)
        # Convert all paths in absolute paths
        for i in (0,2):
            args[i] = os.path.abspath(args[i])
    def run(self):
        optParser = OptionParser(usage=GeneratorScript.__doc__)
        optParser.add_option("-c", "--i18n-clean", action='store_true',
            dest='i18nClean', default=False, help=C_OPTION)
        optParser.add_option("-s", "--i18n-sort", action='store_true',
            dest='i18nSort', default=False, help=S_OPTION)
        (options, args) = optParser.parse_args()
        try:
            self.manageArgs(optParser, options, args)
            print 'Generating %s product in %s...' % (args[1], args[2])
            self.generateProduct(options, *args)
            # Give the user some statistics about its code
            LinesCounter(args[0]).run()
        except GeneratorError, ge:
            sys.stderr.write(str(ge))
            sys.stderr.write('\n')
            optParser.print_help()
            sys.exit(ERROR_CODE)

# ------------------------------------------------------------------------------
if __name__ == '__main__':
    GeneratorScript().run()
# ------------------------------------------------------------------------------