from typing import Union, Any, List, Set, Dict, Tuple, Optional
import json

from prosto.utils import *

from prosto.Prosto import *
from prosto.Table import *
from prosto.Column import *

import logging
log = logging.getLogger('prosto')


class Operation:
    """The class represents one operation."""

    operation_no = 0

    def __init__(self, prosto, definition):
        """
        Create a new operation object using its definition.

        :param prosto: Prosto context object this operation belongs to
        :param definition: Operation definition as a dict
        """

        # Assign id
        self.id = definition.get('id', None)
        if self.id is None:
            self.id = "___operation___" + str(Operation.operation_no)
            definition['id'] = self.id
            Operation.operation_no += 1

        self.prosto = prosto
        self.definition = definition
        self.operation = definition.get("operation")

    def __repr__(self):
        return '['+self.id+']'

    def get_columns(self) -> List[str]:
        """Get a list of input column names specified in this definition."""
        definition = self.definition
        inputs = definition.get('columns', [])

        # If a single name is provided (not a list), then we wrap it into a list
        if isinstance(inputs, str):
            inputs = [inputs]

        return inputs

    def get_outputs(self) -> List[str]:
        """Get a list of output column names generated by this definition."""
        definition = self.definition
        outputs = definition.get('outputs', [])

        # If a single name is provided (not a list), then we wrap it into a list
        if isinstance(outputs, str):
            outputs = [outputs]

        if not outputs:  # If outputs are not specified then use id
            outputs.append(definition.get('id'))

        return outputs


if __name__ == "__main__":
    pass
