from __future__ import absolute_import


import unittest
import os
from glob import glob
import doctest
import json
import pickle
import inspect
import tempfile

_level = os.getenv('IBEX_TEST_LEVEL')
_level = 1 if _level is None else int(_level)


import six
import pandas as pd
import numpy as np
import sklearn
from sklearn import preprocessing
from ibex import frame
from ibex.sklearn import _sklearn_ver
try:
    from sklearn.exceptions import NotFittedError
except ImportError:
    from sklearn.utils.validation import NotFittedError # Older Versions
from ibex.sklearn import preprocessing as pd_preprocessing
from sklearn import pipeline
from ibex.sklearn import pipeline as pd_pipeline
from sklearn import base
from ibex.sklearn import decomposition as pd_decomposition
from sklearn import linear_model
from ibex.sklearn import linear_model as pd_linear_model
from sklearn import ensemble
from ibex.sklearn import ensemble as pd_ensemble
from sklearn import feature_selection
from ibex.sklearn import feature_selection as pd_feature_selection
from sklearn import svm
from ibex.sklearn import svm as pd_svm
from sklearn import gaussian_process
from ibex.sklearn import gaussian_process as pd_gaussian_process
from sklearn import feature_selection
from sklearn import neighbors
from ibex.sklearn import neighbors as pd_neighbors
from sklearn import cluster
from ibex.sklearn import cluster as pd_cluster
from sklearn import decomposition
from ibex.sklearn import decomposition as pd_decomposition
try:
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import GridSearchCV
    from sklearn.model_selection import cross_val_predict
    from ibex.sklearn.model_selection import GridSearchCV as PdGridSearchCV
    from ibex.sklearn.model_selection import cross_val_predict as pd_cross_val_predict
except (ImportError, NameError):
    from sklearn.cross_validation import cross_val_score
    from sklearn.grid_search import GridSearchCV
    from sklearn.cross_validation import cross_val_predict
    from ibex.sklearn.grid_search import GridSearchCV as PdGridSearchCV
    from ibex.sklearn.cross_validation import cross_val_predict as pd_cross_val_predict
from sklearn import datasets
# Tmp Ami - xgboost?
if _level > 0:
    import tensorflow
    from ibex.tensorflow.contrib.keras.wrappers.scikit_learn import KerasClassifier as PdKerasClassifier
    from ibex.tensorflow.contrib.keras.wrappers.scikit_learn import KerasRegressor as PdKerasRegressor
from ibex import *


_tmp_dir = tempfile.mkdtemp()


def _build_regressor_nn():
    model = tensorflow.contrib.keras.models.Sequential()
    model.add(
        tensorflow.contrib.keras.layers.Dense(20, input_dim=4, activation='relu'))
    model.add(
        tensorflow.contrib.keras.layers.Dense(1))

    model.compile(loss='mean_squared_error', optimizer='adagrad')
    return model


def _build_classifier_nn():
    model = tensorflow.contrib.keras.models.Sequential()
    model.add(tensorflow.contrib.keras.layers.Dense(8, input_dim=4, activation='relu'))
    model.add(tensorflow.contrib.keras.layers.Dense(3, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adagrad', metrics=['accuracy'])
    return model


if _level > 0:
    class KerasClassifier(tensorflow.contrib.keras.wrappers.scikit_learn.KerasClassifier, base.ClassifierMixin):
        pass


    class KerasRegressor(tensorflow.contrib.keras.wrappers.scikit_learn.KerasRegressor, base.RegressorMixin):
        pass


_this_dir = os.path.dirname(__file__)


def _load_iris():
    iris = datasets.load_iris()
    features = iris['feature_names']
    iris = pd.DataFrame(
        np.c_[iris['data'], iris['target']],
        columns=features+['class'])
    return iris, features


def _load_digits():
    digits = datasets.load_digits()
    features = ['f%d' % i for i in range(digits['data'].shape[1])]
    digits = pd.DataFrame(
        np.c_[digits['data'], digits['target']],
        columns=features+['digit'])
    digits = digits.sample(frac=0.1).reset_index()
    return digits, features


_dataset_names, _Xs, _ys = [], [], []
_iris, _features = _load_iris()
_dataset_names.append('iris')
_Xs.append(_iris[_features])
_ys.append(_iris['class'])
_Xs.append(_iris[_features])
_ys.append(_iris['class'] == _iris['class'].values[0])
_iris = _iris.copy()
_iris.index = ['i%d' % i for i in range(len(_iris))]
_dataset_names.append('iris_str_index')
_Xs.append(_iris[_features])
_ys.append(_iris['class'])


_estimators = []
_estimators.append((
    preprocessing.StandardScaler(),
    pd_preprocessing.StandardScaler(),
    True))
_estimators.append((
    decomposition.PCA(),
    pd_decomposition.PCA(),
    True))
_estimators.append((
    linear_model.LinearRegression(),
    frame(pd_linear_model.LinearRegression()),
    True))
_estimators.append((
    linear_model.LinearRegression(),