#!/usr/bin/python
# -*- coding: utf-8 -*-

import json

from bson import json_util, ObjectId
from django.utils.translation import ugettext_lazy as _


class BaseDeploymentBackend(object):

    # TODO. Stop using protected property `_deployment_data`.

    def __init__(self, asset):
        self.asset = asset

    def store_data(self, vals=None):
        self.asset._deployment_data.update(vals)

    def delete(self):
        self.asset._deployment_data.clear()

    @classmethod
    def validate_submission_list_params(cls, **kwargs):
        """
        Ensure types of query and each param

        :param query: dict
        :param kwargs: dict
        :return: dict
        """

        start = kwargs.get("start", 0)
        limit = kwargs.get("limit")
        sort = kwargs.get("sort", {})
        fields = kwargs.get("fields", [])
        query = kwargs.get("query", {})
        instances_ids = kwargs.get("instances_ids", [])

        if isinstance(query, basestring):
            try:
                query = json.loads(query, object_hook=json_util.object_hook)
            except ValueError:
                raise ValueError(_("Invalid `query` param"))

        if isinstance(sort, basestring):
            try:
                sort = json.loads(sort, object_hook=json_util.object_hook)
            except ValueError:
                raise ValueError(_("Invalid `sort` param"))

        try:
            start = int(start)
            if start < 0:
                raise ValueError
            if limit is not None:
                limit = int(limit)
                if limit < 0:
                    raise ValueError
        except ValueError:
            raise ValueError(_("Invalid `start/limit` params"))

        if isinstance(fields, basestring):
            try:
                fields = json.loads(fields, object_hook=json_util.object_hook)
            except ValueError:
                raise ValueError(_("Invalid `fields` params"))

        if not isinstance(instances_ids, list):
            raise ValueError(_("Invalid `instances_ids` param"))

        params = {
            "query": query,
            "start": start,
            "fields": fields,
            "sort": sort,
            "instances_ids": instances_ids
        }
        if limit:
            params['limit'] = limit
        return params

    @property
    def backend(self):
        return self.asset._deployment_data.get('backend', None)

    @property
    def identifier(self):
        return self.asset._deployment_data.get('identifier', None)

    @property
    def active(self):
        return self.asset._deployment_data.get('active', False)

    @property
    def version(self):
        raise NotImplementedError('Use `asset.deployment.version_id`')

    @property
    def version_id(self):
        return self.asset._deployment_data.get('version', None)

    @property
    def submission_count(self):
        return self._submission_count()

    @property
    def last_submission_time(self):
        return self._last_submission_time()

    @property
    def mongo_userform_id(self):
        return None

@@ -142,16 +142,54 @@
 zy as _%0A
+from rest_framework import exceptions%0A
 %0A%0Aclass 
@@ -969,16 +969,242 @@
 %22, %5B%5D)%0A%0A
+        # I've copied these %60ValidationError%60 messages verbatim from DRF where%0A        # possible. TODO: Should this validation be in (or called directly by)%0A        # the view code? Does DRF have a validator for GET params?%0A%0A
         
@@ -1388,45 +1388,114 @@
 ise 
-ValueError(_(%22Invalid %60query%60 param%22)
+exceptions.ValidationError(%0A                    %7B'query': _('Value must be valid JSON.')%7D%0A                
 )%0A%0A 
@@ -1683,149 +1683,382 @@
 ise 
-ValueError(_(%22Invalid %60sort%60 param%22))%0A%0A        try:%0A            start = int(start)%0A            if start %3C 0:%0A                raise ValueError
+exceptions.ValidationError(%0A                    %7B'sort': _('Value must be valid JSON.')%7D%0A                )%0A%0A        try:%0A            start = int(start)%0A            if start %3C 0:%0A                raise ValueError%0A        except ValueError:%0A            raise exceptions.ValidationError(%0A                %7B'start': _('A positive integer is required.')%7D%0A            )%0A        try:
 %0A   
@@ -2239,52 +2239,112 @@
 ise 
-ValueError(_(%22Invalid %60start/limit%60 params%22)
+exceptions.ValidationError(%0A                %7B'limit': _('A positive integer is required.')%7D%0A            
 )%0A%0A 
@@ -2538,161 +2538,286 @@
 ise 
-ValueError(_(%22Invalid %60fields%60 params%22))%0A%0A        if not isinstance(instances_ids, list):%0A            raise ValueError(_(%22Invalid %60instances_ids%60 param%22)
+exceptions.ValidationError(%0A                    %7B'fields': _('Value must be valid JSON.')%7D%0A                )%0A%0A        if not isinstance(instances_ids, list):%0A            raise exceptions.ValidationError(%0A                %7B'instances_ids': _('Value must be a list.')%7D%0A            
 )%0A%0A 

Return 400 not 500 if validation fails for…