#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
# Alan Viars

import argparse
import functools
import hashlib
import json
import os
import pymongo
import time
import string
import sys
from collections import OrderedDict
from pymongo import MongoClient


def json2mongo(jsonfile, database_name,
               collection_name,
               delete_collection_before_import,
               host,
               port):
    """Return a response_dict with a summary of json2mongo transaction."""
    # print "Start the import of", jsonfile, "into the collection",
    # collection_name, "within the database", database_name, "."

    response_dict = OrderedDict()
    fileindex = 0
    mongoindex = 0
    error_list = []

    mc = MongoClient(host=host, port=port)
    db = mc[database_name]
    collection = db[collection_name]

    if delete_collection_before_import:
        db.drop_collection(collection)
    fh = open(jsonfile, 'rU')

    j = fh.read()

    try:
        j = json.loads(j, object_pairs_hook=OrderedDict)

        if not isinstance(j, type(OrderedDict())):
            error_message = "File " + \
                str(jsonfile) + " did not contain a JSON object, i.e. {}."
            error_list.append(error_message)

    except:
        error_message = "File " + \
            str(jsonfile) + " did not contain valid JSON."
        error_list.append(error_message)

    if not error_list:

        myobjectid = collection.insert(j)
        mongoindex += 1

        if error_list:
            response_dict['num_files_imported'] = mongoindex
            response_dict['num_file_errors'] = len(error_list)
            response_dict['errors'] = error_list
            response_dict['code'] = 400
            response_dict['message'] = "Completed with errors."

        else:
            response_dict['num_rows_imported'] = mongoindex
            response_dict['num_file_errors'] = len(error_list)
            response_dict['code'] = 200
            response_dict['message'] = "Completed without errors."

    else:
        response_dict['num_rows_imported'] = mongoindex
        response_dict['num_file_errors'] = len(error_list)
        response_dict['code'] = 500
        syserror = sys.exc_info()
        errors = error_list
        if syserror[0]:
            errors.append(str(sys.exc_info()))

        response_dict['errors'] = errors

    return response_dict

if __name__ == "__main__":

    # Parse args
    parser = argparse.ArgumentParser(description='Load in JSON doc to MongoDB')
    parser.add_argument(
        dest='input_JSON_file',
        action='store',
        help='Input the JSON file to load here')
    parser.add_argument(
        dest='db_name',
        action='store',
        help="Enter the Database name you want to import the JSON to")
    parser.add_argument(
        dest='collection_name',
        action='store',
        help="Enter the Collection name within the Database specified that you want the JSON to be imported to")
    parser.add_argument('-d', '--delete', dest='delete', action='store_true',
                        help='Delete previous collection upon import')
    parser.add_argument(
        '--host',
        dest='host',
        action='store',
        default='127.0.0.1',
        help='Specify host. Default is 127.0.0.1 ')
    parser.add_argument(
        '-p',
        '--port',
        dest='port',
        action='store',
        default=27017,
        help='Specify port. Default is 27017')
    args = parser.parse_args()
    json_file = args.input_JSON_file
    database = args.db_name
    collection = args.collection_name
    delete_collection_before_import = args.delete
    host = args.host
    port = args.port

    result = json2mongo(
        json_file,
        database,
        collection,
        delete_collection_before_import,
        host,
        port)

    # output the JSON transaction summary
    print(json.dumps(result, indent=4))
