r"""SentimentTransformer uses TextBlob.sentiment to generate sentiment
    based feature vectors (either lexical or naive bayes).

:Author:
    Matthias Manhertz
:Copyright:
    (c) Matthias Manhertz 2015
:Licence:
    MIT
"""

from .feature_transformer import FeatureTransformer
from .combine import combine_tweets
from time import time
from gensim.models.doc2vec import LabeledSentence, Doc2Vec
import multiprocessing
import numpy as np
import logging


class Doc2VecTransformer(FeatureTransformer):
    r"""Transforms json files into Doc2Vec features

        The Doc2VecTransformer makes it easy to transform .json files
        containing twitter-data (like the ones generated by
        twistml's filtering and / or preprocessing steps) into Doc2Vec
        features.

        <Notes>

        References
        ----------

        Example Usage
        -------------
        ::
            import twistml as tml

            filepaths = tml.find_files('c:/data/')
            d2v = tml.features.Doc2VecTransformer(???)
            features = d2v.transform(filepaths)

    """  # NOQA

    def __init__(self, **kwargs):
        r"""Initialize the Doc2VecTransformer

        Parameters
        ----------


        References
        ----------

        """  # NOQA

        # extract the arguments that are meant for combine_tweets()
        self.tweetargs = {key: value for key, value in kwargs.iteritems()
                          if key in combine_tweets.func_code.co_varnames}

        # sanity check
        d = {key: value for key, value in kwargs.iteritems()
             if key not in combine_tweets.func_code.co_varnames}
        if d:
            raise ValueError('unknown keyword arg(s): {}'.format(d.keys))
        pass

    def transform(self, filepaths):
        r"""Transforms twitter data in files into a dict mapping
            datestamps to Doc2Vec vectors.

            Parameters
            ----------
            filepaths : list(str)
                A list of files that contain tweets in the typical
                format (dict[str, str]) as generated by the filtering
                and / or preprocessing functions in twistml.

            Returns
            -------
            daily_docvecs : dict[datetime, ndarray]
                A dict mapping datestamps to Doc2Vec vectors in numpy
                ndarray format.

        """

        logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s',
                            level=logging.INFO)

        combined = combine_tweets(filepaths, **self.tweetargs)

        t0 = time()
        print "Vectorizing...",
        cores = multiprocessing.cpu_count()
        sentences = LabeledLineSentence(combined)
        model = Doc2Vec(sentences, workers=cores, min_count=2, size=100)

        daily_docvecs = {}
        for date in combined:
            vec = model.docvecs[date.strftime('%Y-%m-%d')]
            daily_docvecs[date] = np.reshape(vec, (1, -1))

        print " done in  {0:.1f}min.".format((time()-t0)/60)

        return daily_docvecs
    pass


class LabeledLineSentence(object):
    def __init__(self, combined_tweets):
        self.combined_tweets = combined_tweets

    def __iter__(self):
        for date, tweets in self.combined_tweets.iteritems():
            yield LabeledSentence(words=tweets.split(),
                                  tags=[date.strftime('%Y-%m-%d')])
