# ......................................................................................
# MIT License

# Copyright (c) 2020-2022 Pantelis I. Kaplanoglou

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# ......................................................................................

from sklearn.model_selection import train_test_split  # import a standalone procedure toyfunction from the pacakge
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from radnn import mlsys
from radnn.data.sample_set_simple import SampleSet
from .constants import DataPreprocessingKind
from enum import Enum


# =========================================================================================================================
class LegacyDataSet(object):
  # --------------------------------------------------------------------------------------
  # Constructor
  def __init__(self, sample_count=None, feature_count=None, class_count=None, random_seed=None):
    # ................................................................
    # // Fields \\
    self.feature_count = feature_count
    self.class_count = class_count
    self.sample_count = sample_count
    self.random_seed = random_seed
    
    self.samples = None
    self.labels = None
    self.preprocessor = None
    self.mean = None
    self.std = None

    # training set object
    self.ts: SampleSet | None = None
    # validation set object
    self.vs: SampleSet | None = None
    # unknown test set object
    self.us: SampleSet | None = None
    # ................................................................
    if self.random_seed is not None:
      mlsys.random_seed_all(self.random_seed)
  # --------------------------------------------------------------------------------------
  def split(self, p_nValidationSamplesPC=0.10, preprocessing: DataPreprocessingKind | None = DataPreprocessingKind.STANDARDIZE):
    oTS_Samples, oVS_Samples, oTS_Labels, oVS_Labels = train_test_split(self.samples, self.labels ,
                                                                        test_size=p_nValidationSamplesPC,
                                                                        random_state=2021)
    if preprocessing == DataPreprocessingKind.MIN_MAX_NORMALIZE:
      self.preprocessor = MinMaxScaler().fit(oTS_Samples)
    elif preprocessing == DataPreprocessingKind.STANDARDIZE:
      self.preprocessor = StandardScaler().fit(oTS_Samples)

    if self.preprocessor is not None:
      oTS_Samples = self.preprocessor.transform(oTS_Samples)
      oVS_Samples = self.preprocessor.transform(oVS_Samples)

    # (Re)creating the subsets of the dataset after the splits have been created
    self.ts = SampleSet(self, oTS_Samples, oTS_Labels)
    self.vs = SampleSet(self, oVS_Samples, oVS_Labels)
    
    print("%d samples in the Training Set" % self.ts.sample_count)
    print("%d samples in the Validation Set" % self.vs.sample_count)
  # --------------------------------------------------------------------------------------
  # Backwards Compatibility
  @property
  def TSSamples(self):
    return self.ts.samples

  @property
  def ts_samples(self):
    return self.ts_samples

  @property
  def TSLabels(self):
    return self.ts.labels

  @property
  def ts_labels(self):
    return self.ts.labels

  @property
  def TSSampleCount(self):
    return self.ts.sample_count

  @property
  def ts_sample_count(self):
    return self.ts.sample_count

  def VSSamples(self):
    return self.vs.samples

  @property
  def vs_samples(self):
    return self.vs.samples

  @property
  def VSLabels(self):
    return self.vs.labels

  @property
  def vs_labels(self):
    return self.vs.labels

  @property
  def VSSampleCount(self):
    return self.vs.sample_count

  @property
  def vs_sample_count(self):
    return self.vs.sample_count

  @property
  def FeatureCount(self):
    return self.feature_count

  @property
  def ClassCount(self):
    return self.class_count

  @property
  def ClassCount(self):
    return self.class_count

  @property
  def SampleCount(self):
    return self.sample_count

  @property
  def Samples(self):
    return self.samples

  @property
  def Labels(self):
    return self.labels
# =========================================================================================================================
