from __future__ import print_function

import argparse
import logging
import sys
import urllib2
import urlparse

from openspending.lib import json

from openspending.model import Source, Dataset, Account
from openspending.model import meta as db
from openspending.importer import CSVImporter
from openspending.importer.analysis import analyze_csv
from openspending.validation.model import validate_model
from openspending.validation.model import Invalid

log = logging.getLogger(__name__)

SHELL_USER = 'system'

import_parser = argparse.ArgumentParser(add_help=False)

import_parser.add_argument('-n', '--dry-run',
                           action="store_true", dest='dry_run', default=False,
                           help="Perform a dry run, don't load any data.")

import_parser.add_argument('--no-index', action="store_false", dest='build_indices',
                           default=True, help='Suppress Solr index build.')

import_parser.add_argument('--max-lines', action="store", dest='max_lines',
                           type=int, default=None, metavar='N',
                           help="Number of lines to import.")

import_parser.add_argument('--raise-on-error', action="store_true",
                           dest='raise_errors', default=False,
                           help='Get full traceback on first error.')

def shell_account():
    account = Account.by_name(SHELL_USER)
    if account is not None:
        return account
    account = Account()
    account.name = SHELL_USER
    db.session.add(account)
    return account

def csvimport(csv_data_url, args):

    def json_of_url(url):
        # Check if it's an internet url (by checking scheme)
        parsed_result = urlparse.urlparse(url)
        if parsed_result.scheme:
            return json.load(urllib2.urlopen(url))
        # If it doesn't have any scheme it's probably a file
        # if not we'll just forward the raised error
        else:
            return json.load(open(url, 'r'))
        
    if not args.model:
        print("You must provide --model!",
              file=sys.stderr)
        sys.exit(1)

    model = json_of_url(args.model)
    try:
        log.info("Validating model")
        model = validate_model(model)
    except Invalid, i:
        log.error("Errors occured during model validation:")
        for field, error in i.asdict().items():
            log.error("%s: %s", field, error)
        sys.exit(1)

    dataset = Dataset.by_name(model['dataset']['name'])
    if dataset is None:
        dataset = Dataset(model)
        db.session.add(dataset)
    log.info("Dataset: %s", dataset.name)

    source = Source(dataset, shell_account(), 
                    csv_data_url)
    # Analyse the csv data and add it to the source
    # If we don't analyse it we'll be left with a weird message
    source.analysis = analyze_csv(csv_data_url)
    for source_ in dataset.sources:
        if source_.url == csv_data_url:
            source = source_
            break
    db.session.add(source)
    db.session.commit()
    
    dataset.generate()
    importer = CSVImporter(source)
    importer.run(**vars(args))

def _csvimport(args):
    # For every url in dataset_urls (arguments) we import it
    for url in args.dataset_urls:
        csvimport(url, args)

def configure_parser(subparser):
    p = subparser.add_parser('csvimport',
                             help='Load a CSV dataset',
                             description='You must specify --model.',
                             parents=[import_parser])
    p.add_argument('--model', action="store", dest='model',
                   default=None, metavar='url',
                   help="URL of JSON format model (metadata and mapping).")
    # Load multiple sources via the dataset_urls (all remaining arguments)
    p.add_argument('dataset_urls', nargs=argparse.REMAINDER, 
                   help="Dataset file URL")
    p.set_defaults(func=_csvimport)


@@ -196,17 +196,23 @@
  Account
+, View
 %0A
-
 from ope
@@ -1553,16 +1553,980 @@
 ccount%0A%0A
+def create_view(dataset, view):%0A    %22%22%22%0A    Create view for a provided dataset from a view provided as dict%0A    %22%22%22%0A%0A    # Check if it exists (if not we create it)%0A    existing = View.by_name(dataset, view%5B'name'%5D)%0A    if existing is None:%0A        # Create the view%0A        view = View()%0A%0A        # Set saved configurations%0A        view.widget = view%5B'widget'%5D%0A        view.state = view%5B'state'%5D%0A        view.name = view%5B'name'%5D%0A        view.label = view%5B'label'%5D%0A        view.description = view%5B'description'%5D%0A        view.public = view%5B'public'%5D%0A        %0A        # Set the dataset as the current dataset%0A        view.dataset = dataset%0A%0A        # Try and set the account provided but if it doesn't exist%0A        # revert to shell account%0A        view.account = Account.by_name(view%5B'account'%5D)%0A        if view.account is None:%0A            view.account = shell_account()%0A%0A        # Commit view to database%0A        db.session.add(view)%0A        db.session.commit()%0A%0A
 def csvi
@@ -4092,16 +4092,212 @@
 args))%0A%0A
+    # Import the views the the user has provided a visualisation file/url%0A    if args.views:%0A        for view in json_of_url(args.views)%5B'visualisations'%5D:%0A            create_view(dataset, view)%0A%0A
 def _csv
@@ -4794,24 +4794,24 @@
 avar='url',%0A
-
             
@@ -4874,16 +4874,264 @@
 ing).%22)%0A
+    # Allow user to define url or file with visualisations%0A    p.add_argument('--visualisations', action=%22store%22, dest=%22views%22,%0A                   default=None, metavar='url/file',%0A                   help=%22URL/file of JSON format visualisations.%22)%0A
     # Lo

Make it possible to import visualisations when import csv files