"""
(C) Copyright 2021 IBM Corp.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Created on June 30, 2021

"""

"""
Augmentor Base class
"""
from abc import ABC, abstractmethod
from typing import Any


class FuseAugmentorBase(ABC):
    """
    Base class for augmentor.
    Given an augmenatation pipline description, expected to sample random parameters first and then apply them.
    """

    @abstractmethod
    def get_random_augmentation_desc(self) -> Any:
        """
        Sample random parameters for augmentation
        :return:
        """
        raise NotImplementedError

    @abstractmethod
    def apply_augmentation(self, sample: Any, augmentation_desc: Any) -> Any:
        """
        Apply the augmenation according to the given parameters. Must be deterministic.
        :param sample: the original sample as generated by the dataset
        :param augmentation_desc: augmentation parameters. Output of get_random_augmentation_desc()
        :return: augmented sample
        """
        raise NotImplementedError

    @abstractmethod
    def summary(self) -> str:
        """
        String summary of the object
        """
        raise NotImplementedError

    def __call__(self, sample: Any):
        """
        generate random and apply the augmentation at once.
        :param sample:
        :return:
        """
        augmentation_desc = self.get_random_augmentation_desc()
        sample_aug = self.apply_augmentation(sample, augmentation_desc)

        return sample_aug
