#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2009 Didier Roche
#
# This file is part of Quickly
#
#This program is free software: you can redistribute it and/or modify it 
#under the terms of the GNU General Public License version 3, as published 
#by the Free Software Foundation.

#This program is distributed in the hope that it will be useful, but 
#WITHOUT ANY WARRANTY; without even the implied warranties of 
#MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
#PURPOSE.  See the GNU General Public License for more details.

#You should have received a copy of the GNU General Public License along 
#with this program.  If not, see <http://www.gnu.org/licenses/>.


import os, re
import sys
import subprocess
import gettext
from gettext import gettext as _

# add quickly root directory (enable symlink, and trunk execution)
quickly_bin_directory = os.path.dirname(os.path.realpath(sys.argv[0]))
quickly_root_directory_name = os.path.dirname(quickly_bin_directory)
quickly_root_directory = os.path.abspath(quickly_root_directory_name)
if os.path.exists(os.path.join(quickly_root_directory, 'quickly')) and quickly_root_directory not in sys.path:
    sys.path.insert(0, quickly_root_directory)
    os.putenv('PYTHONPATH', quickly_root_directory) # for subprocesses

from quickly import commands, configurationhandler, quicklyconfig, coreupgrade, tools, version

gettext.textdomain('quickly')


def main():
    """Main ubuntu command line processor

    :return: exit code of quickly command.
    """

    (opt_command, opt_template) = tools.process_command_line(sys.argv[1:])
    command_name = opt_command[0]
    
    # try to get the template from the project directory if we are in a project (if not already provided by the -t option)
    if not opt_template and configurationhandler.loadConfig(can_stop=False) == 0:
        try:
            opt_template = configurationhandler.project_config['template']
        except KeyError:
            pass

    # check that the command exists in current template
    if opt_template:
        if not tools.check_template_exists(opt_template):
            return(1)

        # with this search, we are sure that only one command: (name,template) is unique
        try:
            command = commands.get_commands_by_criteria(name=command_name, template=opt_template)[0]
        except IndexError:
            # if not found, try for builtins command
            try:
                command = commands.get_commands_by_criteria(name=command_name, template='builtins')[0]
            except IndexError: 
                print _("ERROR: No %s command found in template %s.") % (command_name, opt_template)
                print _("Aborting.")
                return(1)
            
    # from this line, if we don't have a template, only builtins commands and template command followed_by_template are candidates
    else:
        # check for a builtin command (again, one solution only)
        try:
            command = commands.get_commands_by_criteria(name=command_name, template='builtins')[0]    
            # if it's a builtin command which has to be followed by a template, check that everything is correct
            if command.followed_by_template:
                try:
                    # this condition is for the case of, for instance $ quickly help <builtin_command> (no template associated and can be followed by a builtin command)
                    if not (command.followed_by_command and len(opt_command) == 2):
                        opt_template = opt_command[1]
                        opt_command.remove(opt_command[1])
                        if not tools.check_template_exists(opt_template):
                            return(1)
                except IndexError:
                    print _("ERROR: %s command must be followed by a template and no template was found on the command line." % command_name)
                    print _("Candidates template are: %s") % ", ".join(commands.get_all_templates())
                    return(1)
        except IndexError:        
            # so, check for a template command followed by template
            try:
                command = commands.get_commands_by_criteria(name=command_name, template=opt_command[1], followed_by_template=True)[0]
                opt_template = opt_command[1]
                opt_command.remove(opt_command[1])
            except IndexError:
                # to help the user, we can search if this command_name corresponds to a command in a template
                list_possible_commands = commands.get_commands_by_criteria(name=command_name, followed_by_template=True)
                proposed_templates = []
                for template in commands.get_all_templates():
                    try:
                        commands.get_all_commands()[template][command_name]
                        proposed_templates.append(template)
                    except KeyError:
                        pass
                if list_possible_commands:
                    print _("ERROR: %s command must be followed by a template and no template was found on the command line." % command_name)
                    print _("Candidates template are: %s") % ", ".join(proposed_templates)
                else:
                    list_possible_commands = commands.get_commands_by_criteria(name=command_name, followed_by_template=False)
                    if list_possible_commands:
                       print _("No template were found on the command line for command %s." % command_name)
                       print _("Candidates template are: %s") % ", ".join(proposed_templates)                        
                    else:
                        # there is really not such command, in any template
                        print _("ERROR: No %s command found.") % command_name
                print _("Aborting.")
                return(1)

    return(command.launch(os.getcwd(), opt_command[1:], opt_template))


if __name__ == '__main__':

    if len(sys.argv) == 1:
        tools.usage()
        sys.exit(1)
    # core upgrade (very early in the process to upgrade even in shell completion)
    coreupgrade.upgrade()
    # process the command line to send the right instructions
    if sys.argv[1] == 'shell-completion':
        print(" ".join(tools.get_completion_in_context(sys.argv)))
        exit(0)
    else:
        exit(main())

