#  https://github.com/garydoranjr/pyemd

# from emd import emd
from pyemd import emd
from numpy import array
import numpy as np
import gensim, os


# env settings
cur_dir = os.path.dirname(__file__)

project = 'movielens100k'
# project = 'artificial'
# artificial data are generated by simulator module
labelled_data = ['short', 'long'][0]
unlabelled_data = ['short', 'long'][0]
test_file_name = ['te_short', 'te_long'][0]
train_file_name = ['tr_short', 'tr_long'][1]
test_file_path = os.path.join(cur_dir, project, test_file_name)
train_file_path = os.path.join(cur_dir, project, train_file_name)
control_1 = 0
scalar = [0.5, 1, 1.5, 2, 2.5, 3][3]  # 0.5 for sg, 2 for cbow
dimension = [40, 70][0]
top_n = 1
num_item_in_query = 1
num_bins = 5
transaction_folder = os.path.join(cur_dir, project)

# parameters
sample = [True, False][0]
gen_data = [True, False][1]
cbow = [True, False][0]
train = [True, False][control_1]
hs = [0, 1][0]
# alpha = False   # 1 -> short term 0 -> long term    False -> without utility  True -> with utility
alpha = 1  # 1 -> short term 0 -> long term    False -> without utility  True -> with utility
if train:
    epoch = 1
else:
    epoch = 50

'''
movie lens sg
10% remain 0.6

'''


# short term model
model_window_size = 5
model_input_file_name = 'tr_' + unlabelled_data
model_name = unlabelled_data + str(model_window_size) + str(dimension) + ('cbow' if cbow else 'sg') + str(
    scalar).replace('.', '')
model_input_file_path = os.path.join(cur_dir, project, model_input_file_name)
model_path = os.path.join(cur_dir, project, 'models', model_name + '.txt')



# impl
X = np.random.rand(10,50)

for _ in range(19573):

    Y = np.random.rand(10,50)

    # emd(X,Y)
    # print emd(X, Y)

embedding = gensim.models.Word2Vec.load_word2vec_format(model_path, binary=False)
vocab = embedding.vocab
vocab_list = list(vocab.keys())
vocab_idx = range(len(vocab_list))
name2idx = dict(zip(vocab_list, vocab_idx))
idx2name = dict(zip(vocab_idx, vocab_list))

train_set_path = train_file_path
train = (line.strip().split(' ') for line in open(train_set_path, 'r'))

# labels are used in K-nearest neighbor to calculate similar users
# each label is a n-dim histogram
labels = []
for receipt in train:
    this_receipt = [0] * len(name2idx)
    for item in receipt:
        try:
            this_receipt[name2idx[item]] += 1
        except KeyError:
            continue
    labels.append(np.array(this_receipt))

# build distance matrix
vertices = [None] * len(vocab_list)
for i in range(len(vocab_list)):
    vertices[i] = embedding[idx2name[i]]
from sklearn.metrics.pairwise import cosine_similarity
distance_matrix = np.array(cosine_similarity(vertices, vertices)).astype(np.float64)

# build test set
test = (line.strip().split(' ') for line in open(test_file_path, 'r'))
test_set = []
for receipt in test:
    this_receipt = [0] * len(name2idx)
    for item in receipt:
        try:
            this_receipt[name2idx[item]] += 1
        except KeyError:
            continue
    test_set.append(np.array(this_receipt))

labels = np.array(labels).astype(np.float64)
test_set = np.array(test_set).astype(np.float64)
similarity_vector = []
test_sample = test_set[3]
non_zero = np.nonzero(test_sample)[0]
remain = non_zero[:int(len(non_zero)/2)]
removed = non_zero[int(len(non_zero)/2):]
print('removed', removed)
print('remain', remain)
test_sample[removed] = 0
# 1350
# exit()
for label in labels[:]:
    ret = emd(test_sample, label, distance_matrix)
    similarity_vector.append(ret)

similarity_vector = np.array(similarity_vector)
neighbourhood = np.argsort(similarity_vector)[:30]
# print(neighbourhood)
top_similar = similarity_vector[neighbourhood]
import math

normalised_sum = sum([math.exp(x) for x in top_similar])
aggregation = labels[neighbourhood][0]
for user in labels[neighbourhood][1:]:
    # weighted average of reversed softmax
    aggregation += (1 - emd(test_sample, user, distance_matrix)/normalised_sum) * user
    # aggregation += user
print(np.argsort(aggregation)[-5:])
# compute neighborhood U using EMD

# aggregate (weighted average) the items that all users in neighborhood U purchased

# user the top n from ranked items for recommendation