"""
This module holds some static I/O functions.
"""
import codecs
import corpus2
import readers
import tempfile

__author__ = 'blaz'


def load_document(input_path, reader_type, config):
    """
    This function loads document via selected reader and returns the
    corpus2.Document.

    @type input_path: str
    @type reader_type: str
    @type config: saper.config.ConfigLoader
    @rtype corpus2.Document
    """
    reader_class = __get_reader(reader_type)
    reader = reader_class(config)
    document = reader.read_file(input_path)
    return document


def load_documents(input_path, reader_type, config):
    """
    This function loads multiple documents selected via batch file with selected
    reader.

    @type input_path: str
    @type reader_type: str
    @type config: saper.config.ConfigLoader
    @rtype: generator
    """
    reader_class = __get_reader(reader_type)
    reader = reader_class(config)

    batch = codecs.open(input_path, 'r')
    docs_paths = [line.strip() for line in batch.readlines()]
    batch.close()
    
    return (reader.read_file(document_path) for document_path in docs_paths)


def write_ccl_file(document, document_path, tagset):
    """
    Function writes document into ccl file.

    @type document: corpus2.Document
    @type document_path: str
    @type tagset: corpus2.Tagset
    """
    writer = corpus2.TokenWriter_create_path_writer('ccl', document_path,
                                                    tagset)
    for parag in document.paragraphs():
        writer.write_chunk(parag)
    writer.finish()
    del writer


def print_ccl_file(document, tagset):
    """
    Function prints document in ccl file format to stdout.

    @type document: corpus2.Document
    @type tagset: corpus2.Tagset
    """
    printer = corpus2.TokenWriter_create_stdout_writer('ccl', tagset)
    for parag in document.paragraphs():
        printer.write_chunk(parag)
    printer.finish()
    del printer


def write_document_relations(document, output_path, *documents):
    """
    Write relations of a document (or documents) to a file.

    @type document: corpus2.Document
    @type output_path: str
    """
    rel_writer = corpus2.RelationWriter(output_path)
    all_relations = list(document.relations())
    for doc in documents:
        all_relations.extend(doc.relations())
    rel_writer.write(all_relations)
    del rel_writer


def print_document_relations(*documents):
    """
    Print relations of a document (or documents).

    @type documents: iterable corpus2.Document objects
    """
    import string
    import os
    import random

    #Get random string for temporary output
    ran = \
        ''.join([random.choice(string.ascii_letters + string.digits) for n in
                 xrange(32)])
    rel_writer = corpus2.RelationWriter(ran)
    rel_writer.write([rel for doc in documents for rel in doc.relations()])
    del rel_writer
    fi = open(ran, 'r')
    print fi.read()
    fi.close()
    os.remove(ran)


def get_temp_file(document, tagset):
    """
    Method creates temporary ccl format file from given document and returns
    an object of it.

    @type document: DocumentPtr
    @rtype: tempfile.NamedTemporaryFile
    """
    temp = tempfile.NamedTemporaryFile()
    wrtr = corpus2.TokenWriter.create_path_writer('ccl', temp.name,
                                                  tagset)

    #Writing tempfile
    for para in document.paragraphs():
        wrtr.write_chunk(para)
    wrtr.finish()
    del wrtr
    return temp


def __capitalize_nth(s, n):
    """
    This function capitalizes selected letter of some string.

    @type s: str
    @type n: int
    @rtype: str
    """
    return s[:n].lower() + s[n:].capitalize()


def __get_reader(reader_type):
    """
    Function create selected reader object.

    @type reader_type: str
    @rtype: saper.saperio.readers.Reader
    """
    cls = getattr(readers,
                  '%sReader' % __capitalize_nth(reader_type.strip(), 0))
    return cls

