from optparse import make_option
import os
from django.core.management import BaseCommand
import configobj
from django.db.models import get_app, get_model

class Command(BaseCommand):
    """
    Creates django models from config files
    """
    help = """[-a appname ]<config filename>

Create models based on a config file.
The format is:
[<applabel>.<model>]
[[fields]]
field1 = value
field2 = value
[[children]]
[[[<applabel>.<model>]]]
fk_field = <fieldname>
[[[[fields]]]]
field1 = value
field2 = value
"""
    option_list = BaseCommand.option_list + (
        make_option('-a', '--app',
                    action='store',
                    dest='app',
                    default = '<default app label>',
                    help='application to get the config file from'),
        )

    def get_config(self, app_label, config_filename):
        if not config_filename.endswith('.cfg'):
            config_filename += '.cfg'
        app_module = get_app(app_label)
        if hasattr(app_module, '__path__'):
            app_path = app_module.__path__
        else:
            app_path = app_module.__file__
        filename = os.path.join(os.path.dirname(app_path),
                                'config',
                                config_filename)
        return configobj.ConfigObj(filename)

    def create_object(self, model, cfg, parent=None):
        app_label, modelname = model.split('.')
        ModelClass = get_model(app_label, modelname)
        kwargs = {}
        if parent is not None:
            kwargs[cfg['fk_field']] = parent
        kwargs.update(cfg['fields'])
        obj, new = ModelClass.objects.get_or_create(**kwargs)
        if not new:
            self.stdout.write('%s object with fields %s already exists: id %d' % (
                model, str(cfg['fields']), obj.pk))
        return obj

    def handle(self, *args, **options):
        if not args:
            print "The config file is required"
            return
        config = self.get_config(options['app'], args[0])
        for model, cfg in config.items():
            obj = self.create_object(model, cfg)
            for childmodel, ccfg in cfg['children'].items():
                child = self.create_object(childmodel, ccfg, parent=obj)