# Path: fdep/config.py
# class FdepConfig(object):
#     """Serialize and unserialize fdep configuration file."""
# 
#     def __init__(self, root_path, config_dict):
#         """Initialize a fdep configuration object with a dictionary."""
#         self.root_path = root_path
#         self._config = config_dict
# 
#     def save(self, path=None):
#         """Save a fdep configuration object into a YAML file."""
#         if path is None:
#             path = os.path.join(self.root_path, 'fdep.yml')
#         with open(path, 'w') as f:
#             f.write(yaml.dump(self._config, default_flow_style=False))
# 
#     def __getitem__(self, key):
#         """Get the item in a coherent manner.
# 
#         We have two types of entries: just a string type, and a dictionary type.
#         We convert anything into the new dictionary type.
#         e.g. "http://foo.bar" => {"source": "http://foo.bar"}
#         """
#         return FdepEntryDictionary(self._config[key])
# 
#     def __setitem__(self, key, value):
#         """Set the item in order to make the config file prettier.
# 
#         If the object only has the key "source", we convert it into a string.
#         """
#         if not isinstance(value, FdepEntryDictionary):
#             raise Exception("An FdepEntryDictionary object is expected.")
#         self._config[key] = value._dict
# 
#     def __delitem__(self, key):
#         del self._config[key]
# 
#     def get(self, key):
#         """Implement an exception-free getter."""
#         if key not in self._config:
#             return None
#         return self[key]
# 
#     @classmethod
#     def load(cls, path):
#         """Load a fdep configuration from a YAML file."""
#         if not os.path.exists(path):
#             return None
# 
#         with open(path) as f:
#             root_path = os.path.dirname(path)
#             return FdepConfig(root_path, yaml.load(f.read()))
# 
#     @classmethod
#     def find_root_path(cls, current_path='.'):
#         """Find a relative path that has the configuration."""
#         paths_to_search = set()
#         current_path = [current_path]
# 
#         while True:
#             path = os.path.abspath(
#                 os.path.join(*current_path)
#             )
#             if path in paths_to_search:
#                 break
# 
#             paths_to_search.add(path)
#             current_path.append('..')
# 
#         sorted_paths = sorted(
#             list(paths_to_search),
#             key=lambda x: -len(x)
#         )
# 
#         # Search going down the tree
#         for path in sorted_paths:
#             config_path = os.path.join(path, 'fdep.yml')
#             if os.path.exists(config_path):
#                 return path
#         return None
# 
# Path: fdep/runner.py
# class FdepRunner(CommandRunner):
#     """Implement the root runner.
# 
#     This manages subcommand runners and runs them with the proper context.
#     """
#     AVAILABLE_COMMANDS = [
#         HelpCommandRunner,
#         VersionCommandRunner,
#         AddCommandRunner,
#         InstallCommandRunner,
#         UnfreezeCommandRunner,
#         FreezeCommandRunner,
#         InitCommandRunner,
#         MvCommandRunner,
#         RmCommandRunner,
#         CommitCommandRunner,
#         UploadCommandRunner,
#         LinkCommandRunner,
#         ServeCommandRunner,
#     ]
#     AVAILABLE_BACKENDS = [
#         HTTPBackend,
#         HTTPSBackend,
#         S3Backend,
#         GSpreadsheetBackend,
#     ]
# 
#     def __init__(self, env, config):
#         self.env = env
#         self.config = config
#         self.path_helper = PathHelper(env, config)
#         self.messages = messages.FdepDefaultMessages
# 
#         # Build tables
#         self.commands = {klass.COMMAND_NAME: klass(self) for klass in self.__class__.AVAILABLE_COMMANDS}
#         self.backends = {klass.SCHEME_NAME: klass for klass in self.__class__.AVAILABLE_BACKENDS}
# 
#     def run(self, *args, **kwargs):
#         """Interpret the argv and run appropriate methods."""
#         args = list(args)
#         print(self.messages.CURRENT_ENVIRONMENT.format(self.env), file=sys.stderr)
#         if not len(args):
#             cmd = command = None
#         else:
#             cmd = args.pop(0)
#             command = self.commands.get(cmd)
# 
#         if not command:
#             if cmd:
#                 sys.stderr.write(self.messages.UNRECOGNIZED_COMMAND.format(cmd))
#             command = self.commands['help']
#         return command.validate_and_run(*args, **kwargs)


import os
import sys
from fdep.config import FdepConfig
from fdep.runner import FdepRunner



def parse_argv(argv):
    """Implement a manual option parser."""
    argv = list(argv)
    args, kwargs = [], {}

    while len(argv):
        arg = argv.pop(0)
        if arg[0] == '-' and len(arg) >= 2:
            ind = 2 if arg[1] == '-' else 1
            kv = arg[ind:].split('=', 1)
            if len(kv) == 1:
                kv.append(argv.pop(0))
            kwargs[kv[0]] = kv[1]
        else:
            args.append(arg)
    return args, kwargs


def main(argv=None):
    """Implement the entry point of fdep."""
    if argv is None:
        argv = sys.argv
    root_path = FdepConfig.find_root_path() or os.getcwd()
    env = os.environ.get('ENV', 'development')

# Path: fdep/config.py
# class FdepConfig(object):
#     """Serialize and unserialize fdep configuration file."""
# 
#     def __init__(self, root_path, config_dict):
#         """Initialize a fdep configuration object with a dictionary."""
#         self.root_path = root_path
#         self._config = config_dict
# 
#     def save(self, path=None):
#         """Save a fdep configuration object into a YAML file."""
#         if path is None:
#             path = os.path.join(self.root_path, 'fdep.yml')
#         with open(path, 'w') as f:
#             f.write(yaml.dump(self._config, default_flow_style=False))
# 
#     def __getitem__(self, key):
#         """Get the item in a coherent manner.
# 
#         We have two types of entries: just a string type, and a dictionary type.
#         We convert anything into the new dictionary type.
#         e.g. "http://foo.bar" => {"source": "http://foo.bar"}
#         """
#         return FdepEntryDictionary(self._config[key])
# 
#     def __setitem__(self, key, value):
#         """Set the item in order to make the config file prettier.
# 
#         If the object only has the key "source", we convert it into a string.
#         """
#         if not isinstance(value, FdepEntryDictionary):
#             raise Exception("An FdepEntryDictionary object is expected.")
#         self._config[key] = value._dict
# 
#     def __delitem__(self, key):
#         del self._config[key]
# 
#     def get(self, key):
#         """Implement an exception-free getter."""
#         if key not in self._config:
#             return None
#         return self[key]
# 
#     @classmethod
#     def load(cls, path):
#         """Load a fdep configuration from a YAML file."""
#         if not os.path.exists(path):
#             return None
# 
#         with open(path) as f:
#             root_path = os.path.dirname(path)
#             return FdepConfig(root_path, yaml.load(f.read()))
# 
#     @classmethod
#     def find_root_path(cls, current_path='.'):
#         """Find a relative path that has the configuration."""
#         paths_to_search = set()
#         current_path = [current_path]
# 
#         while True:
#             path = os.path.abspath(
#                 os.path.join(*current_path)
#             )
#             if path in paths_to_search:
#                 break
# 
#             paths_to_search.add(path)
#             current_path.append('..')
# 
#         sorted_paths = sorted(
#             list(paths_to_search),
#             key=lambda x: -len(x)
#         )
# 
#         # Search going down the tree
#         for path in sorted_paths:
#             config_path = os.path.join(path, 'fdep.yml')
#             if os.path.exists(config_path):
#                 return path
#         return None
# 
# Path: fdep/runner.py
# class FdepRunner(CommandRunner):
#     """Implement the root runner.
# 
#     This manages subcommand runners and runs them with the proper context.
#     """
#     AVAILABLE_COMMANDS = [
#         HelpCommandRunner,
#         VersionCommandRunner,
#         AddCommandRunner,
#         InstallCommandRunner,
#         UnfreezeCommandRunner,
#         FreezeCommandRunner,
#         InitCommandRunner,
#         MvCommandRunner,
#         RmCommandRunner,
#         CommitCommandRunner,
#         UploadCommandRunner,
#         LinkCommandRunner,
#         ServeCommandRunner,
#     ]
#     AVAILABLE_BACKENDS = [
#         HTTPBackend,
#         HTTPSBackend,
#         S3Backend,
#         GSpreadsheetBackend,
#     ]
# 
#     def __init__(self, env, config):
#         self.env = env
#         self.config = config
#         self.path_helper = PathHelper(env, config)
#         self.messages = messages.FdepDefaultMessages
# 
#         # Build tables
#         self.commands = {klass.COMMAND_NAME: klass(self) for klass in self.__class__.AVAILABLE_COMMANDS}
#         self.backends = {klass.SCHEME_NAME: klass for klass in self.__class__.AVAILABLE_BACKENDS}
# 
#     def run(self, *args, **kwargs):
#         """Interpret the argv and run appropriate methods."""
#         args = list(args)
#         print(self.messages.CURRENT_ENVIRONMENT.format(self.env), file=sys.stderr)
#         if not len(args):
#             cmd = command = None
#         else:
#             cmd = args.pop(0)
#             command = self.commands.get(cmd)
# 
#         if not command:
#             if cmd:
#                 sys.stderr.write(self.messages.UNRECOGNIZED_COMMAND.format(cmd))
#             command = self.commands['help']
#         return command.validate_and_run(*args, **kwargs)


# Path: fdep/__main__.py
import os
import sys
from fdep.config import FdepConfig
from fdep.runner import FdepRunner




def parse_argv(argv):
    """Implement a manual option parser."""
    argv = list(argv)
    args, kwargs = [], {}

    while len(argv):
        arg = argv.pop(0)
        if arg[0] == '-' and len(arg) >= 2:
            ind = 2 if arg[1] == '-' else 1
            kv = arg[ind:].split('=', 1)
            if len(kv) == 1:
                kv.append(argv.pop(0))
            kwargs[kv[0]] = kv[1]
        else:
            args.append(arg)
    return args, kwargs


def main(argv=None):
    """Implement the entry point of fdep."""
    if argv is None:
        argv = sys.argv
    root_path = FdepConfig.find_root_path() or os.getcwd()
    env = os.environ.get('ENV', 'development')

    config = FdepConfig.load(os.path.join(root_path, 'fdep.yml'))