#!python
# Copyright 2013-2017 by Luc Saffre.
# License: BSD, see LICENSE for more details.

from __future__ import print_function
import os
import subprocess
import argparse

from atelier import rstgen
from atelier.projects import load_projects
from argh import dispatch_command, arg, CommandError

@dispatch_command
@arg('cmd', 
     nargs=argparse.REMAINDER,
     help="The command to run on every project.")
@arg('-l', '--list', default=False, dest='showlist',
     help='Show list of projects.')
@arg('-s', '--start',
     help='Start from that project, skip those before.')
@arg('-a', '--after',
     help='Start after that project, skip those before.')
@arg('-u', '--until',
     help='Only until that project, skip those after.')
@arg('-v', '--voice',
     help='Speak the result through speakers when terminated.')
def main(voice=False, start=None, after=None, until=None, showlist=False, *cmd):
    """Loop over all projects, executing the given shell command in the
root directory of each project.  See
http://atelier.lino-framework.org/usage.html

    """
    if showlist:
        headers = (
            'Project',
            # 'Version',
            'Status',
            'URL',
            'doctrees')

        def cells(self):
            self.load_tasks()
            yield self.nickname
            # yield self.SETUP_INFO.get('version', '')
            yield self.get_status()
            yield self.SETUP_INFO.get('url', None)
            yield ', '.join(self.doc_trees)

        print(rstgen.table(headers, [
            tuple(cells(p)) for p in load_projects()]))
        if len(cmd) == 0:
            return
            
    if len(cmd) == 0:
        raise CommandError("You must specify a command!")

    def saymsg(msg):
        if voice:
            msg = msg.replace("'", "\'")
            cmd = ("espeak", "'{}'".format(msg))
            subprocess.call(cmd)

    skipping = start is not None or after is not None
    for prj in load_projects():
        if cmd[0] == 'git':
            prj.load_tasks()
            if prj.config['revision_control_system'] != 'git':
                continue
        if start and prj.nickname == start:
            skipping = False
        if after and prj.nickname == after:
            skipping = False
            continue
        if skipping:
            continue
        if until and prj.nickname == until:
            skipping = True
        print("==== %s ====" % prj.nickname)
        os.chdir(prj.root_dir)
        rv = subprocess.call(cmd, cwd=prj.root_dir)
        if rv:
            msg = "%s ended with error %s in project %s" % (
                ' '.join(cmd), rv, prj.nickname)
            saymsg(msg)
            raise CommandError(msg)

    msg = "Successfully terminated `{}` for all projects"
    msg = msg.format(' '.join(cmd))
    saymsg(msg)
    print(msg)
