from __future__ import print_function, absolute_import
import argparse


class App(object):
    """Main parser"""

    def __init__(self, name, **kwargs):
        """
        Create a CLI parser.

        Args:
            name (str): Application name.
            kwargs (dict): Dictionary of parameters supported by argparse.ArgumentParser.
        """
        self.name = name
        self._type = 'app'
        self.parser = argparse.ArgumentParser(prog=name, **kwargs)
        self.sub_parser = None

    @property
    def type(self):
        """
        The command type.

        Returns:
            str
        """
        return self._type

    @property
    def command_group(self):
        """
        Returns the sub parser of the application.

        Returns:

        """
        if not self.sub_parser:
            self.sub_parser = self.parser.add_subparsers()
        return self.sub_parser

    def add_argument(self, *args, **kwargs):
        """
        Add optional arguments.

        Args:
            *args:
            **kwargs:

        See Also:
            argparse.parser.add_argument()

        Returns:

        """
        self.parser.add_argument(*args, **kwargs)

    def parse_args(self, *args, **kwargs):
        return self.parser.parse_args(*args, **kwargs)


class Command(object):
    """Positional command argument parser"""
    def __init__(self, parent, name):
        """
        Creates a positional argument.

        Args:
            parent: To object to add this command to. Either an `App` or another `Command`.
            name: The argument name.
        """
        self.name = name
        self._type = 'command'
        self.parser = parent.command_group.add_parser(name)
        if parent.type == 'command':
            self.parser.set_defaults(command='{0}_{1}'.format(parent.name, name))
        else:
            self.parser.set_defaults(command='{0}'.format(name))
        self.sub_parser = None

    @property
    def type(self):
        """
        The command type.

        Returns:
            str
        """
        return self._type

    @property
    def command_group(self):
        """
        Returns the sub parser of the command.

        Returns:

        """
        if not self.sub_parser:
            self.sub_parser = self.parser.add_subparsers()
        return self.sub_parser

    def add_argument(self, *args, **kwargs):
        """
        Add optional arguments.

        Args:
            *args:
            **kwargs:

        See Also:
            argparse.parser.add_argument()

        Returns:

        """
        self.parser.add_argument(*args, **kwargs)

@@ -72,19 +72,27 @@
 %0A%0Aclass 
-App
+BaseCommand
 (object)
@@ -101,107 +101,114 @@
     
-%22%22%22Main parser%22%22%22%0A%0A    def __init__(self, name, **kwargs):%0A        %22%22%22%0A        Create a CLI parser.
+TYPE_APP = 'app'%0A    TYPE_COMMAND = 'command'%0A%0A    def __init__(self, name, cmd_type, parser):%0A        %22%22%22
 %0A%0A  
@@ -247,19 +247,15 @@
 r): 
-Application
+Command
  nam
@@ -273,84 +273,82 @@
     
-kwargs (dict): Dictionary of parameters supported by argparse.ArgumentParser
+cmd_type (str): Command type.%0A            parser: argparse's parser object
 .%0A  
@@ -403,21 +403,24 @@
 _type = 
-'app'
+cmd_type
 %0A       
@@ -438,52 +438,14 @@
 r = 
-arg
 parse
-.ArgumentParser(prog=name, **kwargs)
+r
 %0A   
@@ -1167,16 +1167,481 @@
 wargs)%0A%0A
+%0Aclass App(BaseCommand):%0A    %22%22%22Main parser.%22%22%22%0A%0A    def __init__(self, name, **kwargs):%0A        %22%22%22%0A        Create a CLI parser.%0A%0A        Args:%0A            name (str): Application name.%0A            kwargs (dict): Dictionary of parameters supported by argparse.ArgumentParser.%0A        %22%22%22%0A        super(App, self).__init__(%0A            name=name,%0A            cmd_type=BaseCommand.TYPE_APP,%0A            parser=argparse.ArgumentParser(prog=name, **kwargs)%0A        )%0A%0A
     def 
@@ -1742,30 +1742,35 @@
 ass Command(
-object
+BaseCommand
 ):%0A    %22%22%22Po
@@ -1801,16 +1801,17 @@
 t parser
+.
 %22%22%22%0A    
@@ -1881,24 +1881,32 @@
  positional 
+command 
 argument.%0A%0A 
@@ -2072,32 +2072,70 @@
    s
-elf.
+uper(Command, self).__init__(%0A            
 name
- = 
+=
 name
-%0A
+,%0A 
         
 self
@@ -2134,39 +2134,58 @@
     
-self._type = 'command'%0A
+   cmd_type=BaseCommand.TYPE_COMMAND,%0A    
         
 self
@@ -2180,30 +2180,23 @@
         
-self.
 parser
- = 
+=
 parent.c
@@ -2225,16 +2225,26 @@
 r(name)%0A
+        )%0A
         
@@ -2261,25 +2261,40 @@
 type == 
-'c
+BaseC
 ommand
-'
+.TYPE_COMMAND
 :%0A      
@@ -2452,725 +2452,4 @@
 e))%0A
-        self.sub_parser = None%0A%0A    @property%0A    def type(self):%0A        %22%22%22%0A        The command type.%0A%0A        Returns:%0A            str%0A        %22%22%22%0A        return self._type%0A%0A    @property%0A    def command_group(self):%0A        %22%22%22%0A        Returns the sub parser of the command.%0A%0A        Returns:%0A%0A        %22%22%22%0A        if not self.sub_parser:%0A            self.sub_parser = self.parser.add_subparsers()%0A        return self.sub_parser%0A%0A    def add_argument(self, *args, **kwargs):%0A        %22%22%22%0A        Add optional arguments.%0A%0A        Args:%0A            *args:%0A            **kwargs:%0A%0A        See Also:%0A            argparse.parser.add_argument()%0A%0A        Returns:%0A%0A        %22%22%22%0A        self.parser.add_argument(*args, **kwargs)%0A

refactor oi module for better code reusage