from traitlets import default

from .baseapp import NbGrader, nbgrader_aliases, nbgrader_flags
from ..exchange import Exchange, ExchangeFetch, ExchangeError


aliases = {}
aliases.update(nbgrader_aliases)
aliases.update({
    "timezone": "Exchange.timezone",
    "course": "Exchange.course_id",
})

flags = {}
flags.update(nbgrader_flags)
flags.update({
    'replace': (
        {'ExchangeFetch' : {'replace_missing_files' : True}},
        "replace missing files, even if the assignment has already been fetched"
    ),
})


class FetchApp(NbGrader):

    name = u'nbgrader-fetch'
    description = u'Fetch an assignment from the nbgrader exchange'

    aliases = aliases
    flags = flags

    examples = """
        Fetch an assignment that an instructor has released. For the usage of students.

        You can run this command from any directory, but usually, you will have a
        directory where you are keeping your course assignments.

        To fetch an assignment by name into the current directory:

            nbgrader fetch assignment1

        To fetch an assignment for a specific course, you must first know the
        `course_id` for your course.  If you don't know it, ask your instructor.
        Then, simply include the argument with the '--course' flag.

            nbgrader fetch assignment1 --course=phys101

        This will create an new directory named `assignment1` where you can work
        on the assignment. When you are done, use the `nbgrader submit` command
        to turn in the assignment.
        """

    @default("classes")
    def _classes_default(self):
        classes = super(FetchApp, self)._classes_default()
        classes.extend([Exchange, ExchangeFetch])
        return classes

    def _load_config(self, cfg, **kwargs):
        if 'FetchApp' in cfg:
            self.log.warning(
                "Use ExchangeFetch in config, not FetchApp. Outdated config:\n%s",
                '\n'.join(
                    'FetchApp.{key} = {value!r}'.format(key=key, value=value)
                    for key, value in cfg.FetchApp.items()
                )
            )
            cfg.ExchangeFetch.merge(cfg.FetchApp)
            del cfg.FetchApp

        super(FetchApp, self)._load_config(cfg, **kwargs)

    def start(self):
        super(FetchApp, self).start()

        # set assignment and course
        if len(self.extra_args) == 0:
            self.fail("Must provide assignment name:\nnbgrader <command> ASSIGNMENT [ --course COURSE ]")

        failed = False

        for arg in self.extra_args:
            self.coursedir.assignment_id = arg
            fetch = ExchangeFetch(coursedir=self.coursedir, parent=self)
            try:
                fetch.start()
            except ExchangeError:
                failed = True

        if failed:
            self.fail("nbgrader fetch failed")

@@ -2385,16 +2385,55 @@
 gs) == 0
+ and self.coursedir.assignment_id == %22%22
 :%0A      
@@ -2545,71 +2545,10 @@
     
+i
 f
-ailed = False%0A%0A        for arg in self.extra_args:%0A           
  sel
@@ -2577,13 +2577,14 @@
 _id 
+!
 = 
-arg
+%22%22:
 %0A   
@@ -2734,16 +2734,374 @@
 eError:%0A
+                self.fail(%22nbgrader fetch failed%22)%0A        else:%0A            failed = False%0A%0A            for arg in self.extra_args:%0A                self.coursedir.assignment_id = arg%0A                fetch = ExchangeFetch(coursedir=self.coursedir, parent=self)%0A                try:%0A                    fetch.start()%0A                except ExchangeError:%0A    
         
@@ -3123,16 +3123,20 @@
 = True%0A%0A
+    
         
@@ -3146,16 +3146,20 @@
 failed:%0A
+    
         

Handle positional argument