from gen.console.input import Input, Config, Option, Argument
from gen.console.output import Output

class Command:
  command = None
  describe = ''

  __app = None
  __input = None
  __output = None
  __parameters = []

  @property
  def app(self):
    return self.__app

  @property
  def input(self) -> Input:
    return self.__input

  @property
  def output(self) -> Output:
    return self.__output

  @property
  def parameter(self) -> list:
    return self.__parameters

  def setup(self):
    pass

  def exec(self, input: Input, output: Output):
    raise Exception('You must override exec output')

  def option(self, command: str, shortcut: str = None, help: str = '', type = str, default = None) -> Config:
    return self.parameter(Option(
      command=command,
      shortcut=shortcut,
      help=help,
      type=type,
      default=default,
    ))

  def options(self):
    options = {}

    for parameter in filter(lambda parameter: isinstance(parameter, Option),self.__parameters):
      if parameter.command() not in options:
        options.update({ parameter.command(): parameter })

    return options
    
  def argument(self, command: str, help: str = '', type = str, default = None) -> Config:
    return self.parameter(Argument(
      command=command,
      help=help,
      type=type,
      default=default,
    ))

  def arguments(self):
    return [ parameter for parameter in self.__parameters if isinstance(parameter, Argument) ]

  def parameter(self, parameter: Config):
    self.__parameters.append(parameter)

    return parameter

  def dispatch(self, app, input: Input, output: Output):
    self.__app = app
    self.__input = input
    self.__output = output

    if self.setup() or not self.setup():
      input.create(self.__parameters)

      if input.option('help', False) or input.argument('help', False):
        app.help(self)
      else:
        app.code(self.exec(input, output))
from gen.console.input import Input, Config, Option, Argument
from gen.console.output import Output

class Command:
  command = None
  describe = ''

  __app = None
  __input = None
  __output = None
  __parameters = []

  @property
  def app(self):
    return self.__app

  @property
  def input(self) -> Input:
    return self.__input

  @property
  def output(self) -> Output:
    return self.__output

  @property
  def parameter(self) -> list:
    return self.__parameters

  def setup(self):
    pass

  def exec(self, input: Input, output: Output):
    raise Exception('You must override exec output')

  def option(self, command: str, shortcut: str = None, help: str = '', type = str, default = None) -> Config:
    return self.parameter(Option(
      command=command,
      shortcut=shortcut,
      help=help,
      type=type,
      default=default,
    ))

  def options(self):
    options = {}

    for parameter in filter(lambda parameter: isinstance(parameter, Option),self.__parameters):
      if parameter.command() not in options:
        options.update({ parameter.command(): parameter })

    return options
    
  def argument(self, command: str, help: str = '', type = str, default = None) -> Config:
    return self.parameter(Argument(
      command=command,
      help=help,
      type=type,
      default=default,
    ))

  def arguments(self):
    return [ parameter for parameter in self.__parameters if isinstance(parameter, Argument) ]

  def parameter(self, parameter: Config):
    self.__parameters.append(parameter)

    return parameter

  def dispatch(self, app, input: Input, output: Output):
    self.__app = app
    self.__input = input
    self.__output = output

    if self.setup() or not self.setup():
      input.create(self.__parameters)

      if input.option('help', False) or input.argument('help', False):
        app.help(self)
      else:
        app.code(self.exec(input, output))