###################################################################################
# LAVA QA tool
# Copyright (C) 2015, 2016 Collabora Ltd.

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

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

# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  US
###################################################################################

import re
import json
from datetime import datetime

from lqa_api.job import Job
from lqa_api.connection import Connection
from lqa_api.exit_codes import APPLICATION_ERROR
from lqa_tool.settings import settings, lqa_logger
from lqa_api.utils import job_id_list_from_range, RangeNotationError

class Command(object):
    """Base object for lqa commands.

    :param args: The parsed arguments as returned by argparse.
    """

    def __init__(self, args):
        self.args = args
        self.settings = settings
        self.server = Connection(self.settings.rpc_url)
        # Only build the job id list if the command has the 'job_ids' argument,
        # otherwise just return.
        if args.__dict__.get('job_ids', None):
            try:
                self.job_ids = job_id_list_from_range(self.args.job_ids)
            except RangeNotationError as e:
                lqa_logger.error(e)
                exit(APPLICATION_ERROR)

class QueueCommand(Command):
    """This class contains the common logic for the commands working with jobs
    queue: queue and cleanqueue"""

    def __init__(self, args):
        Command.__init__(self, args)

    def run(self, func):
        date = datetime.strptime(self.args.date, "%Y%m%d").date() \
               if self.args.date else None

        names_regexp = []
        for name in self.args.name:
            names_regexp.append(re.compile(name))

        for job_data in self.server.all_jobs():
            job = Job(job_data[0], self.server)
            # Filter options
            if names_regexp:
                if not any(map(lambda r: r.search(job.name), names_regexp)):
                    continue
            if date and not job.submit_time.date() <= date:
                continue
            if self.args.device and job.device_type not in self.args.device:
                continue
            if self.args.hostname and job.hostname not in self.args.hostname:
                continue
            if self.args.worker_host and \
               job.worker_host not in self.args.worker_host:
                continue
            if self.args.user and \
               self.args.user != job.details['submitter_username']:
                continue

            # Call passed function after filtering.
            func(job, self.server, job_data, self.args)
