# Path: unstyle/feat_select.py
# def ak_means_cluster(X, numAuthors):
#     """Given a set of feature values, cluster them into k groups. If, after
#     convergence, there are less than 3 points in any given cluster, recurse with
#     ak_means_cluster(featureVec, numAuthors - 1).
# 
#     :param X: Values for a given feature across a set of authors.
#     :rtype: A tuple containing (a trained k-means cluster, numAuthors)
#     """
#     if numAuthors < 1:
#         raise ValueError("ak-means initialized with less than 1 cluster.")
# 
#     km = KMeans(n_clusters=numAuthors, init='k-means++', n_jobs=-1)
#     km.fit(X)
# 
#     # Check number of features found in each cluster. Restart with k - 1 if
#     # there are less than 3 members of any cluster.
#     # First, we count the number of members in each cluster:
#     labelTable = {}
#     for label in km.labels_:
#         if label in labelTable:
#             labelTable[label] += 1
#         else:
#             labelTable[label] = 1
# 
#     # Now we check if any clusters have less than three members:
#     for label in labelTable.keys():
#         if labelTable[label] < 3:
#             print("Reinitializing k means with ", numAuthors - 1, " clusters.")
#             return ak_means_cluster(X, numAuthors - 1)
#     return (km, numAuthors)


from unstyle.feat_select import ak_means_cluster
import numpy as np
import random
import sys
"""Module containing functions related to defeating stylometry.
"""


def compute_target_vals(docfeatures, X, classifier, featureSet, numAuthors):
    """Given a set of feature vectors and a trained classifier, determine what
    each feature must be changed to change the classifier's label of the set of
    feature vectors.

    :param docfeatures: The feature vector of the document we are trying to
    anonymize.
    :param X: A complete feature set composed of the feature vectors from
    other_user_documents and other_author_documents.
    :param classifier: A classifier trained on X.
    :param featureSet: A feature extractor, such as Basic9Extractor().
    :param numAuthors: The number of authors in X.
    :rtype: A list of target vectors for each feature.
    """
    # TODO: Split this function up; it's very monolithic
    # Cluster every feature vector; put them all in a list.
    print("Clustering features...")
    clusterMeansList = []
    for col in range(X.shape[1]):
        # Get every sample of a given feature; cluster into <= numAuthors
        # groups.
        feature = np.asmatrix(X[:, col]).transpose()
        print("Clustering the following samples:")
        print(feature)

# Path: unstyle/feat_select.py
# def ak_means_cluster(X, numAuthors):
#     """Given a set of feature values, cluster them into k groups. If, after
#     convergence, there are less than 3 points in any given cluster, recurse with
#     ak_means_cluster(featureVec, numAuthors - 1).
# 
#     :param X: Values for a given feature across a set of authors.
#     :rtype: A tuple containing (a trained k-means cluster, numAuthors)
#     """
#     if numAuthors < 1:
#         raise ValueError("ak-means initialized with less than 1 cluster.")
# 
#     km = KMeans(n_clusters=numAuthors, init='k-means++', n_jobs=-1)
#     km.fit(X)
# 
#     # Check number of features found in each cluster. Restart with k - 1 if
#     # there are less than 3 members of any cluster.
#     # First, we count the number of members in each cluster:
#     labelTable = {}
#     for label in km.labels_:
#         if label in labelTable:
#             labelTable[label] += 1
#         else:
#             labelTable[label] = 1
# 
#     # Now we check if any clusters have less than three members:
#     for label in labelTable.keys():
#         if labelTable[label] < 3:
#             print("Reinitializing k means with ", numAuthors - 1, " clusters.")
#             return ak_means_cluster(X, numAuthors - 1)
#     return (km, numAuthors)


# Path: unstyle/adversarial.py
from unstyle.feat_select import ak_means_cluster
import numpy as np
import random
import sys

"""Module containing functions related to defeating stylometry.
"""


def compute_target_vals(docfeatures, X, classifier, featureSet, numAuthors):
    """Given a set of feature vectors and a trained classifier, determine what
    each feature must be changed to change the classifier's label of the set of
    feature vectors.

    :param docfeatures: The feature vector of the document we are trying to
    anonymize.
    :param X: A complete feature set composed of the feature vectors from
    other_user_documents and other_author_documents.
    :param classifier: A classifier trained on X.
    :param featureSet: A feature extractor, such as Basic9Extractor().
    :param numAuthors: The number of authors in X.
    :rtype: A list of target vectors for each feature.
    """
    # TODO: Split this function up; it's very monolithic
    # Cluster every feature vector; put them all in a list.
    print("Clustering features...")
    clusterMeansList = []
    for col in range(X.shape[1]):
        # Get every sample of a given feature; cluster into <= numAuthors
        # groups.
        feature = np.asmatrix(X[:, col]).transpose()
        print("Clustering the following samples:")
        print(feature)

        ak = ak_means_cluster(feature, numAuthors)