# -*- coding: utf-8 -*-
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility module for translating XML API objects to/from JSON objects."""

from __future__ import absolute_import

import datetime
import json
import re
import textwrap
import xml.etree.ElementTree

from apitools.base.py import encoding
import boto
from boto.gs.acl import ACL
from boto.gs.acl import ALL_AUTHENTICATED_USERS
from boto.gs.acl import ALL_USERS
from boto.gs.acl import Entries
from boto.gs.acl import Entry
from boto.gs.acl import GROUP_BY_DOMAIN
from boto.gs.acl import GROUP_BY_EMAIL
from boto.gs.acl import GROUP_BY_ID
from boto.gs.acl import USER_BY_EMAIL
from boto.gs.acl import USER_BY_ID

from gslib.cloud_api import ArgumentException
from gslib.cloud_api import BucketNotFoundException
from gslib.cloud_api import NotFoundException
from gslib.cloud_api import Preconditions
from gslib.exception import CommandException
from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages

# In Python 2.6, ElementTree raises ExpatError instead of ParseError.
# pylint: disable=g-import-not-at-top
try:
  from xml.etree.ElementTree import ParseError as XmlParseError
except ImportError:
  from xml.parsers.expat import ExpatError as XmlParseError

CACHE_CONTROL_REGEX = re.compile(r'^cache-control', re.I)
CONTENT_DISPOSITION_REGEX = re.compile(r'^content-disposition', re.I)
CONTENT_ENCODING_REGEX = re.compile(r'^content-encoding', re.I)
CONTENT_LANGUAGE_REGEX = re.compile(r'^content-language', re.I)
CONTENT_MD5_REGEX = re.compile(r'^content-md5', re.I)
CONTENT_TYPE_REGEX = re.compile(r'^content-type', re.I)
GOOG_API_VERSION_REGEX = re.compile(r'^x-goog-api-version', re.I)
GOOG_GENERATION_MATCH_REGEX = re.compile(r'^x-goog-if-generation-match', re.I)
GOOG_METAGENERATION_MATCH_REGEX = re.compile(
    r'^x-goog-if-metageneration-match', re.I)
CUSTOM_GOOG_METADATA_REGEX = re.compile(r'^x-goog-meta-(?P<header_key>.*)',
                                        re.I)
CUSTOM_AMZ_METADATA_REGEX = re.compile(r'^x-amz-meta-(?P<header_key>.*)', re.I)
CUSTOM_AMZ_HEADER_REGEX = re.compile(r'^x-amz-(?P<header_key>.*)', re.I)

# gsutil-specific GUIDs for marking special metadata for S3 compatibility.
S3_ACL_MARKER_GUID = '3b89a6b5-b55a-4900-8c44-0b0a2f5eab43-s3-AclMarker'
S3_DELETE_MARKER_GUID = 'eadeeee8-fa8c-49bb-8a7d-0362215932d8-s3-DeleteMarker'
S3_MARKER_GUIDS = [S3_ACL_MARKER_GUID, S3_DELETE_MARKER_GUID]
# This distinguishes S3 custom headers from S3 metadata on objects.
S3_HEADER_PREFIX = 'custom-amz-header'

DEFAULT_CONTENT_TYPE = 'application/octet-stream'

# Because CORS is just a list in apitools, we need special handling or blank
# CORS lists will get sent with other configuration commands such as lifecycle,
# which would cause CORS configuration to be unintentionally removed.
# Protorpc defaults list values to an empty list, and won't allow us to set the
# value to None like other configuration fields, so there is no way to
# distinguish the default value from when we actually want to remove the CORS
# configuration.  To work around this, we create a dummy CORS entry that
# signifies that we should nullify the CORS configuration.
# A value of [] means don't modify the CORS configuration.
# A value of REMOVE_CORS_CONFIG means remove the CORS configuration.
REMOVE_CORS_CONFIG = [apitools_messages.Bucket.CorsValueListEntry(
    maxAgeSeconds=-1, method=['REMOVE_CORS_CONFIG'])]

# Similar to CORS above, we need a sentinel value allowing us to specify
# when a default object ACL should be private (containing no entries).
# A defaultObjectAcl value of [] means don't modify the default object ACL.
# A value of [PRIVATE_DEFAULT_OBJ_ACL] means create an empty/private default
# object ACL.
PRIVATE_DEFAULT_OBJ_ACL = apitools_messages.ObjectAccessControl(
    id='PRIVATE_DEFAULT_OBJ_ACL')


def ObjectMetadataFromHeaders(headers):
  """Creates object metadata according to the provided headers.

  gsutil -h allows specifiying various headers (originally intended
  to be passed to boto in gsutil v3).  For the JSON API to be compatible with
  this option, we need to parse these headers into gsutil_api Object fields.

  Args:
    headers: Dict of headers passed via gsutil -h

  Raises:
    ArgumentException if an invalid header is encountered.

  Returns:
    apitools Object with relevant fields populated from headers.
  """
  obj_metadata = apitools_messages.Object()
  for header, value in headers.items():
    if CACHE_CONTROL_REGEX.match(header):
      obj_metadata.cacheControl = value.strip()
    elif CONTENT_DISPOSITION_REGEX.match(header):
      obj_metadata.contentDisposition = value.strip()
    elif CONTENT_ENCODING_REGEX.match(header):
      obj_metadata.contentEncoding = value.strip()
    elif CONTENT_MD5_REGEX.match(header):
      obj_metadata.md5Hash = value.strip()
    elif CONTENT_LANGUAGE_REGEX.match(header):
      obj_metadata.contentLanguage = value.strip()
    elif CONTENT_TYPE_REGEX.match(header):
      if not value:
        obj_metadata.contentType = DEFAULT_CONTENT_TYPE
      else:
        obj_metadata.contentType = value.strip()
    elif GOOG_API_VERSION_REGEX.match(header):
      # API version is only relevant for XML, ignore and rely on the XML API
      # to add the appropriate version.
      continue
    elif GOOG_GENERATION_MATCH_REGEX.match(header):
      # Preconditions are handled elsewhere, but allow these headers through.
      continue
    elif GOOG_METAGENERATION_MATCH_REGEX.match(header):
      # Preconditions are handled elsewhere, but allow these headers through.
      continue
    else:
      custom_goog_metadata_match = CUSTOM_GOOG_METADATA_REGEX.match(header)
      custom_amz_metadata_match = CUSTOM_AMZ_METADATA_REGEX.match(header)
      custom_amz_header_match = CUSTOM_AMZ_HEADER_REGEX.match(header)
      header_key = None
      if custom_goog_metadata_match:
        header_key = custom_goog_metadata_match.group('header_key')
      elif custom_amz_metadata_match:
        header_key = custom_amz_metadata_match.group('header_key')
      elif custom_amz_header_match:
        # If we got here we are guaranteed by the prior statement that this is
        # not an x-amz-meta- header.
        header_key = (S3_HEADER_PREFIX +
                      custom_amz_header_match.group('header_key'))
      if header_key:
        if header_key.lower() == 'x-goog-content-language':
          # Work around content-language being inserted into custom metadata.
          continue
        if not obj_metadata.metadata:
          obj_metadata.metadata = apitools_messages.Object.MetadataValue()
        if not obj_metadata.metadata.additionalProperties:
          obj_metadata.metadata.additionalProperties = []
        obj_metadata.metadata.additionalProperties.append(
            apitools_messages.Object.MetadataValue.AdditionalProperty(
                key=header_key, value=value))
      else:
        raise ArgumentException(
            'Invalid header specifed: %s:%s' % (header, value))
  return obj_metadata


def HeadersFromObjectMetadata(dst_obj_metadata, provider):
  """Creates a header dictionary based on existing object metadata.

  Args:
    dst_obj_metadata: Object metadata to create the headers from.
    provider: Provider string ('gs' or 's3')

  Returns:
    Headers dictionary.
  """
  headers = {}
  if not dst_obj_metadata:
    return
  # Metadata values of '' mean suppress/remove this header.
  if dst_obj_metadata.cacheControl is not None:
    if not dst_obj_metadata.cacheControl:
      headers['cache-control'] = None
    else:
      headers['cache-control'] = dst_obj_metadata.cacheControl.strip()
  if dst_obj_metadata.contentDisposition:
    if not dst_obj_metadata.contentDisposition:
      headers['content-disposition'] = None
    else:
      headers['content-disposition'] = (
          dst_obj_metadata.contentDisposition.strip())
  if dst_obj_metadata.contentEncoding:
    if not dst_obj_metadata.contentEncoding:
      headers['content-encoding'] = None
    else:
      headers['content-encoding'] = dst_obj_metadata.contentEncoding.strip()
  if dst_obj_metadata.contentLanguage:
    if not dst_obj_metadata.contentLanguage:
      headers['content-language'] = None
    else:
      headers['content-language'] = dst_obj_metadata.contentLanguage.strip()
  if dst_obj_metadata.md5Hash:
    if not dst_obj_metadata.md5Hash:
      headers['Content-MD5'] = None
    else:
      headers['Content-MD5'] = dst_obj_metadata.md5Hash.strip()
  if dst_obj_metadata.contentType is not None:
    if not dst_obj_metadata.contentType:
      headers['content-type'] = None
    else:
      headers['content-type'] = dst_obj_metadata.contentType.strip()
  if (dst_obj_metadata.metadata and
      dst_obj_metadata.metadata.additionalProperties):
    for additional_property in dst_obj_metadata.metadata.additionalProperties:
      # Work around content-language being inserted into custom metadata by
      # the XML API.
      if additional_property.key == 'content-language':
        continue
      # Don't translate special metadata markers.
      if additional_property.key in S3_MARKER_GUIDS:
        continue
      if provider == 'gs':
        header_name = 'x-goog-meta-' + additional_property.key
      elif provider == 's3':
        if additional_property.key.startswith(S3_HEADER_PREFIX):
          header_name = ('x-amz-' +
                         additional_property.key[len(S3_HEADER_PREFIX):])
        else:
          header_name = 'x-amz-meta-' + additional_property.key
      else:
        raise ArgumentException('Invalid provider specified: %s' % provider)
      if (additional_property.value is not None and
          not additional_property.value):
        headers[header_name] = None
      else:
        headers[header_name] = additional_property.value
  return headers


def CopyObjectMetadata(src_obj_metadata, dst_obj_metadata, override=False):
  """Copies metadata from src_obj_metadata to dst_obj_metadata.

  Args:
    src_obj_metadata: Metadata from source object
    dst_obj_metadata: Initialized metadata for destination object
    override: If true, will overwrite metadata in destination object.
              If false, only writes metadata for values that don't already
              exist.
  """
  if override or not dst_obj_metadata.cacheControl:
    dst_obj_metadata.cacheControl = src_obj_metadata.cacheControl
  if override or not dst_obj_metadata.contentDisposition:
    dst_obj_metadata.contentDisposition = src_obj_metadata.contentDisposition
  if override or not dst_obj_metadata.contentEncoding:
    dst_obj_metadata.contentEncoding = src_obj_metadata.contentEncoding
  if override or not dst_obj_metadata.contentLanguage:
    dst_obj_metadata.contentLanguage = src_obj_metadata.contentLanguage
  if override or not dst_obj_metadata.contentType:
    dst_obj_metadata.contentType = src_obj_metadata.contentType
  if override or not dst_obj_metadata.md5Hash:
    dst_obj_metadata.md5Hash = src_obj_metadata.md5Hash

  # TODO: Apitools should ideally treat metadata like a real dictionary instead
  # of a list of key/value pairs (with an O(N^2) lookup).  In practice the
  # number of values is typically small enough not to matter.
  # Work around this by creating our own dictionary.
  if (src_obj_metadata.metadata and
      src_obj_metadata.metadata.additionalProperties):
    if not dst_obj_metadata.metadata:
      dst_obj_metadata.metadata = apitools_messages.Object.MetadataValue()
    if not dst_obj_metadata.metadata.additionalProperties:
      dst_obj_metadata.metadata.additionalProperties = []
    dst_metadata_dict = {}
    for dst_prop in dst_obj_metadata.metadata.additionalProperties:
      dst_metadata_dict[dst_prop.key] = dst_prop.value
    for src_prop in src_obj_metadata.metadata.additionalProperties:
      if src_prop.key in dst_metadata_dict:
        if override:
          # Metadata values of '' mean suppress/remove this header.
          if src_prop.value is not None and not src_prop.value:
            dst_metadata_dict[src_prop.key] = None
          else:
            dst_metadata_dict[src_prop.key] = src_prop.value
      else:
        dst_metadata_dict[src_prop.key] = src_prop.value
    # Rewrite the list with our updated dict.
    dst_obj_metadata.metadata.additionalProperties = []
    for k, v in dst_metadata_dict.iteritems():
      dst_obj_metadata.metadata.additionalProperties.append(
          apitools_messages.Object.MetadataValue.AdditionalProperty(key=k,
                                                                    value=v))


def PreconditionsFromHeaders(headers):
  """Creates bucket or object preconditions acccording to the provided headers.

  Args:
    headers: Dict of headers passed via gsutil -h

  Returns:
    gsutil Cloud API Preconditions object fields populated from headers, or None
    if no precondition headers are present.
  """
  return_preconditions = Preconditions()
  try:
    for header, value in headers.items():
      if GOOG_GENERATION_MATCH_REGEX.match(header):
        return_preconditions.gen_match = long(value)
      if GOOG_METAGENERATION_MATCH_REGEX.match(header):
        return_preconditions.meta_gen_match = long(value)
  except ValueError, _:
    raise ArgumentException('Invalid precondition header specified. '
                            'x-goog-if-generation-match and '
                            'x-goog-if-metageneration match must be specified '
                            'with a positive integer value.')
  return return_preconditions


def CreateNotFoundExceptionForObjectWrite(
    dst_provider, dst_bucket_name, src_provider=None,
    src_bucket_name=None, src_object_name=None, src_generation=None):
  """Creates a NotFoundException for an object upload or copy.

  This is necessary because 404s don't necessarily specify which resource
  does not exist.

  Args:
    dst_provider: String abbreviation of destination provider, e.g., 'gs'.
    dst_bucket_name: Destination bucket name for the write operation.
    src_provider: String abbreviation of source provider, i.e. 'gs', if any.
    src_bucket_name: Source bucket name, if any (for the copy case).
    src_object_name: Source object name, if any (for the copy case).
    src_generation: Source object generation, if any (for the copy case).

  Returns:
    NotFoundException with appropriate message.
  """
  dst_url_string = '%s://%s' % (dst_provider, dst_bucket_name)
  if src_bucket_name and src_object_name:
    src_url_string = '%s://%s/%s' % (src_provider, src_bucket_name,
                                     src_object_name)
    if src_generation:
      src_url_string += '#%s' % str(src_generation)
    return NotFoundException(
        'The source object %s or the destination bucket %s does not exist.' %
        (src_url_string, dst_url_string))

  return NotFoundException(
      'The destination bucket %s does not exist or the write to the '
      'destination must be restarted' % dst_url_string)


def CreateBucketNotFoundException(code, provider, bucket_name):
  return BucketNotFoundException('%s://%s bucket does not exist.' %
                                 (provider, bucket_name), bucket_name,
                                 status=code)


def CreateObjectNotFoundException(code, provider, bucket_name, object_name,
                                  generation=None):
  uri_string = '%s://%s/%s' % (provider, bucket_name, object_name)
  if generation:
    uri_string += '#%s' % str(generation)
  return NotFoundException('%s does not exist.' % uri_string, status=code)


def EncodeStringAsLong(string_to_convert):
  """Encodes an ASCII string as a python long.

  This is used for modeling S3 version_id's as apitools generation.  Because
  python longs can be arbitrarily large, this works.

  Args:
    string_to_convert: ASCII string to convert to a long.

  Returns:
    Long that represents the input string.
  """
  return long(string_to_convert.encode('hex'), 16)


def _DecodeLongAsString(long_to_convert):
  """Decodes an encoded python long into an ASCII string.

  This is used for modeling S3 version_id's as apitools generation.

  Args:
    long_to_convert: long to convert to ASCII string. If this is already a
                     string, it is simply returned.

  Returns:
    String decoded from the input long.
  """
  if isinstance(long_to_convert, basestring):
    # Already converted.
    return long_to_convert
  return hex(long_to_convert)[2:-1].decode('hex')


def GenerationFromUrlAndString(url, generation):
  """Decodes a generation from a StorageURL and a generation string.

  This is used to represent gs and s3 versioning.

  Args:
    url: StorageUrl representing the object.
    generation: Long or string representing the object's generation or
                version.

  Returns:
    Valid generation string for use in URLs.
  """
  if url.scheme == 's3' and generation:
    return _DecodeLongAsString(generation)
  return generation


def CheckForXmlConfigurationAndRaise(config_type_string, json_txt):
  """Checks a JSON parse exception for provided XML configuration."""
  try:
    xml.etree.ElementTree.fromstring(str(json_txt))
    raise ArgumentException('\n'.join(textwrap.wrap(
        'XML {0} data provided; Google Cloud Storage {0} configuration '
        'now uses JSON format. To convert your {0}, set the desired XML '
        'ACL using \'gsutil {1} set ...\' with gsutil version 3.x. Then '
        'use \'gsutil {1} get ...\' with gsutil version 4 or greater to '
        'get the corresponding JSON {0}.'.format(config_type_string,
                                                 config_type_string.lower()))))
  except XmlParseError:
    pass
  raise ArgumentException('JSON %s data could not be loaded '
                          'from: %s' % (config_type_string, json_txt))


class LifecycleTranslation(object):
  """Functions for converting between various lifecycle formats.

    This class handles conversation to and from Boto Cors objects, JSON text,
    and apitools Message objects.
  """

  @classmethod
  def BotoLifecycleFromMessage(cls, lifecycle_message):
    """Translates an apitools message to a boto lifecycle object."""
    boto_lifecycle = boto.gs.lifecycle.LifecycleConfig()
    if lifecycle_message:
      for rule_message in lifecycle_message.rule:
        boto_rule = boto.gs.lifecycle.Rule()
        if (rule_message.action and rule_message.action.type and
            rule_message.action.type.lower() == 'delete'):
          boto_rule.action = boto.gs.lifecycle.DELETE
        if rule_message.condition:
          if rule_message.condition.age:
            boto_rule.conditions[boto.gs.lifecycle.AGE] = (
                str(rule_message.condition.age))
          if rule_message.condition.createdBefore:
            boto_rule.conditions[boto.gs.lifecycle.CREATED_BEFORE] = (
                str(rule_message.condition.createdBefore))
          if rule_message.condition.isLive:
            boto_rule.conditions[boto.gs.lifecycle.IS_LIVE] = (
                str(rule_message.condition.isLive))
          if rule_message.condition.numNewerVersions:
            boto_rule.conditions[boto.gs.lifecycle.NUM_NEWER_VERSIONS] = (
                str(rule_message.condition.numNewerVersions))
        boto_lifecycle.append(boto_rule)
    return boto_lifecycle

  @classmethod
  def BotoLifecycleToMessage(cls, boto_lifecycle):
    """Translates a boto lifecycle object to an apitools message."""
    lifecycle_message = None
    if boto_lifecycle:
      lifecycle_message = apitools_messages.Bucket.LifecycleValue()
      for boto_rule in boto_lifecycle:
        lifecycle_rule = (
            apitools_messages.Bucket.LifecycleValue.RuleValueListEntry())
        lifecycle_rule.condition = (apitools_messages.Bucket.LifecycleValue.
                                    RuleValueListEntry.ConditionValue())
        if boto_rule.action and boto_rule.action == boto.gs.lifecycle.DELETE:
          lifecycle_rule.action = (apitools_messages.Bucket.LifecycleValue.
                                   RuleValueListEntry.ActionValue(
                                       type='Delete'))
        if boto.gs.lifecycle.AGE in boto_rule.conditions:
          lifecycle_rule.condition.age = int(
              boto_rule.conditions[boto.gs.lifecycle.AGE])
        if boto.gs.lifecycle.CREATED_BEFORE in boto_rule.conditions:
          lifecycle_rule.condition.createdBefore = (
              LifecycleTranslation.TranslateBotoLifecycleTimestamp(
                  boto_rule.conditions[boto.gs.lifecycle.CREATED_BEFORE]))
        if boto.gs.lifecycle.IS_LIVE in boto_rule.conditions:
          lifecycle_rule.condition.isLive = bool(
              boto_rule.conditions[boto.gs.lifecycle.IS_LIVE])
        if boto.gs.lifecycle.NUM_NEWER_VERSIONS in boto_rule.conditions:
          lifecycle_rule.condition.numNewerVersions = int(
              boto_rule.conditions[boto.gs.lifecycle.NUM_NEWER_VERSIONS])
        lifecycle_message.rule.append(lifecycle_rule)
    return lifecycle_message

  @classmethod
  def JsonLifecycleFromMessage(cls, lifecycle_message):
    """Translates an apitools message to lifecycle JSON."""
    return str(encoding.MessageToJson(lifecycle_message)) + '\n'

  @classmethod
  def JsonLifecycleToMessage(cls, json_txt):
    """Translates lifecycle JSON to an apitools message."""
    try:
      deserialized_lifecycle = json.loads(json_txt)
      # If lifecycle JSON is the in the following format
      # {'lifecycle': {'rule': ... then strip out the 'lifecycle' key
      # and reduce it to the following format
      # {'rule': ...
      if 'lifecycle' in deserialized_lifecycle:
        deserialized_lifecycle = deserialized_lifecycle['lifecycle']
      lifecycle = encoding.DictToMessage(
          deserialized_lifecycle, apitools_messages.Bucket.LifecycleValue)
      return lifecycle
    except ValueError:
      CheckForXmlConfigurationAndRaise('lifecycle', json_txt)

  @classmethod
  def TranslateBotoLifecycleTimestamp(cls, lifecycle_datetime):
    """Parses the timestamp from the boto lifecycle into a datetime object."""
    return datetime.datetime.strptime(lifecycle_datetime, '%Y-%m-%d').date()


class CorsTranslation(object):
  """Functions for converting between various CORS formats.

    This class handles conversation to and from Boto Cors objects, JSON text,
    and apitools Message objects.
  """

  @classmethod
  def BotoCorsFromMessage(cls, cors_message):
    """Translates an apitools message to a boto Cors object."""
    cors = boto.gs.cors.Cors()
    cors.cors = []
    for collection_message in cors_message:
      collection_elements = []
      if collection_message.maxAgeSeconds:
        collection_elements.append((boto.gs.cors.MAXAGESEC,
                                    str(collection_message.maxAgeSeconds)))
      if collection_message.method:
        method_elements = []
        for method in collection_message.method:
          method_elements.append((boto.gs.cors.METHOD, method))
        collection_elements.append((boto.gs.cors.METHODS, method_elements))
      if collection_message.origin:
        origin_elements = []
        for origin in collection_message.origin:
          origin_elements.append((boto.gs.cors.ORIGIN, origin))
        collection_elements.append((boto.gs.cors.ORIGINS, origin_elements))
      if collection_message.responseHeader:
        header_elements = []
        for header in collection_message.responseHeader:
          header_elements.append((boto.gs.cors.HEADER, header))
        collection_elements.append((boto.gs.cors.HEADERS, header_elements))
      cors.cors.append(collection_elements)
    return cors

  @classmethod
  def BotoCorsToMessage(cls, boto_cors):
    """Translates a boto Cors object to an apitools message."""
    message_cors = []
    if boto_cors.cors:
      for cors_collection in boto_cors.cors:
        if cors_collection:
          collection_message = apitools_messages.Bucket.CorsValueListEntry()
          for element_tuple in cors_collection:
            if element_tuple[0] == boto.gs.cors.MAXAGESEC:
              collection_message.maxAgeSeconds = int(element_tuple[1])
            if element_tuple[0] == boto.gs.cors.METHODS:
              for method_tuple in element_tuple[1]:
                collection_message.method.append(method_tuple[1])
            if element_tuple[0] == boto.gs.cors.ORIGINS:
              for origin_tuple in element_tuple[1]:
                collection_message.origin.append(origin_tuple[1])
            if element_tuple[0] == boto.gs.cors.HEADERS:
              for header_tuple in element_tuple[1]:
                collection_message.responseHeader.append(header_tuple[1])
          message_cors.append(collection_message)
    return message_cors

  @classmethod
  def JsonCorsToMessageEntries(cls, json_cors):
    """Translates CORS JSON to an apitools message.

    Args:
      json_cors: JSON string representing CORS configuration.

    Returns:
      List of apitools Bucket.CorsValueListEntry. An empty list represents
      no CORS configuration.
    """
    try:
      deserialized_cors = json.loads(json_cors)
      cors = []
      for cors_entry in deserialized_cors:
        cors.append(encoding.DictToMessage(
            cors_entry, apitools_messages.Bucket.CorsValueListEntry))
      return cors
    except ValueError:
      CheckForXmlConfigurationAndRaise('CORS', json_cors)

  @classmethod
  def MessageEntriesToJson(cls, cors_message):
    """Translates an apitools message to CORS JSON."""
    json_text = ''
    # Because CORS is a MessageField, serialize/deserialize as JSON list.
    json_text += '['
    printed_one = False
    for cors_entry in cors_message:
      if printed_one:
        json_text += ','
      else:
        printed_one = True
      json_text += encoding.MessageToJson(cors_entry)
    json_text += ']\n'
    return json_text


def S3MarkerAclFromObjectMetadata(object_metadata):
  """Retrieves GUID-marked S3 ACL from object metadata, if present.

  Args:
    object_metadata: Object metadata to check.

  Returns:
    S3 ACL text, if present, None otherwise.
  """
  if (object_metadata and object_metadata.metadata and
      object_metadata.metadata.additionalProperties):
    for prop in object_metadata.metadata.additionalProperties:
      if prop.key == S3_ACL_MARKER_GUID:
        return prop.value


def AddS3MarkerAclToObjectMetadata(object_metadata, acl_text):
  """Adds a GUID-marked S3 ACL to the object metadata.

  Args:
    object_metadata: Object metadata to add the acl to.
    acl_text: S3 ACL text to add.
  """
  if not object_metadata.metadata:
    object_metadata.metadata = apitools_messages.Object.MetadataValue()
  if not object_metadata.metadata.additionalProperties:
    object_metadata.metadata.additionalProperties = []

  object_metadata.metadata.additionalProperties.append(
      apitools_messages.Object.MetadataValue.AdditionalProperty(
          key=S3_ACL_MARKER_GUID, value=acl_text))


class AclTranslation(object):
  """Functions for converting between various ACL formats.

    This class handles conversion to and from Boto ACL objects, JSON text,
    and apitools Message objects.
  """

  JSON_TO_XML_ROLES = {'READER': 'READ', 'WRITER': 'WRITE',
                       'OWNER': 'FULL_CONTROL'}
  XML_TO_JSON_ROLES = {'READ': 'READER', 'WRITE': 'WRITER',
                       'FULL_CONTROL': 'OWNER'}

  @classmethod
  def BotoAclFromJson(cls, acl_json):
    acl = ACL()
    acl.parent = None
    acl.entries = cls.BotoEntriesFromJson(acl_json, acl)
    return acl

  @classmethod
  # acl_message is a list of messages, either object or bucketaccesscontrol
  def BotoAclFromMessage(cls, acl_message):
    acl_dicts = []
    for message in acl_message:
      if message == PRIVATE_DEFAULT_OBJ_ACL:
        # Sentinel value indicating acl_dicts should be an empty list to create
        # a private (no entries) default object ACL.
        break
      acl_dicts.append(encoding.MessageToDict(message))
    return cls.BotoAclFromJson(acl_dicts)

  @classmethod
  def BotoAclToJson(cls, acl):
    if hasattr(acl, 'entries'):
      return cls.BotoEntriesToJson(acl.entries)
    return []

  @classmethod
  def BotoObjectAclToMessage(cls, acl):
    for entry in cls.BotoAclToJson(acl):
      message = encoding.DictToMessage(entry,
                                       apitools_messages.ObjectAccessControl)
      message.kind = u'storage#objectAccessControl'
      yield message

  @classmethod
  def BotoBucketAclToMessage(cls, acl):
    for entry in cls.BotoAclToJson(acl):
      message = encoding.DictToMessage(entry,
                                       apitools_messages.BucketAccessControl)
      message.kind = u'storage#bucketAccessControl'
      yield message

  @classmethod
  def BotoEntriesFromJson(cls, acl_json, parent):
    entries = Entries(parent)
    entries.parent = parent
    entries.entry_list = [cls.BotoEntryFromJson(entry_json)
                          for entry_json in acl_json]
    return entries

  @classmethod
  def BotoEntriesToJson(cls, entries):
    return [cls.BotoEntryToJson(entry) for entry in entries.entry_list]

  @classmethod
  def BotoEntryFromJson(cls, entry_json):
    """Converts a JSON entry into a Boto ACL entry."""
    entity = entry_json['entity']
    permission = cls.JSON_TO_XML_ROLES[entry_json['role']]
    if entity.lower() == ALL_USERS.lower():
      return Entry(type=ALL_USERS, permission=permission)
    elif entity.lower() == ALL_AUTHENTICATED_USERS.lower():
      return Entry(type=ALL_AUTHENTICATED_USERS, permission=permission)
    elif entity.startswith('project'):
      raise CommandException('XML API does not support project scopes, '
                             'cannot translate ACL.')
    elif 'email' in entry_json:
      if entity.startswith('user'):
        scope_type = USER_BY_EMAIL
      elif entity.startswith('group'):
        scope_type = GROUP_BY_EMAIL
      return Entry(type=scope_type, email_address=entry_json['email'],
                   permission=permission)
    elif 'entityId' in entry_json:
      if entity.startswith('user'):
        scope_type = USER_BY_ID
      elif entity.startswith('group'):
        scope_type = GROUP_BY_ID
      return Entry(type=scope_type, id=entry_json['entityId'],
                   permission=permission)
    elif 'domain' in entry_json:
      if entity.startswith('domain'):
        scope_type = GROUP_BY_DOMAIN
      return Entry(type=scope_type, domain=entry_json['domain'],
                   permission=permission)
    raise CommandException('Failed to translate JSON ACL to XML.')

  @classmethod
  def BotoEntryToJson(cls, entry):
    """Converts a Boto ACL entry to a valid JSON dictionary."""
    acl_entry_json = {}
    # JSON API documentation uses camel case.
    scope_type_lower = entry.scope.type.lower()
    if scope_type_lower == ALL_USERS.lower():
      acl_entry_json['entity'] = 'allUsers'
    elif scope_type_lower == ALL_AUTHENTICATED_USERS.lower():
      acl_entry_json['entity'] = 'allAuthenticatedUsers'
    elif scope_type_lower == USER_BY_EMAIL.lower():
      acl_entry_json['entity'] = 'user-%s' % entry.scope.email_address
      acl_entry_json['email'] = entry.scope.email_address
    elif scope_type_lower == USER_BY_ID.lower():
      acl_entry_json['entity'] = 'user-%s' % entry.scope.id
      acl_entry_json['entityId'] = entry.scope.id
    elif scope_type_lower == GROUP_BY_EMAIL.lower():
      acl_entry_json['entity'] = 'group-%s' % entry.scope.email_address
      acl_entry_json['email'] = entry.scope.email_address
    elif scope_type_lower == GROUP_BY_ID.lower():
      acl_entry_json['entity'] = 'group-%s' % entry.scope.id
      acl_entry_json['entityId'] = entry.scope.id
    elif scope_type_lower == GROUP_BY_DOMAIN.lower():
      acl_entry_json['entity'] = 'domain-%s' % entry.scope.domain
      acl_entry_json['domain'] = entry.scope.domain
    else:
      raise ArgumentException('ACL contains invalid scope type: %s' %
                              scope_type_lower)

    acl_entry_json['role'] = cls.XML_TO_JSON_ROLES[entry.permission]
    return acl_entry_json

  @classmethod
  def JsonToMessage(cls, json_data, message_type):
    """Converts the input JSON data into list of Object/BucketAccessControls.

    Args:
      json_data: String of JSON to convert.
      message_type: Which type of access control entries to return,
                    either ObjectAccessControl or BucketAccessControl.

    Raises:
      ArgumentException on invalid JSON data.

    Returns:
      List of ObjectAccessControl or BucketAccessControl elements.
    """
    try:
      deserialized_acl = json.loads(json_data)

      acl = []
      for acl_entry in deserialized_acl:
        acl.append(encoding.DictToMessage(acl_entry, message_type))
      return acl
    except ValueError:
      CheckForXmlConfigurationAndRaise('ACL', json_data)

  @classmethod
  def JsonFromMessage(cls, acl):
    """Strips unnecessary fields from an ACL message and returns valid JSON.

    Args:
      acl: iterable ObjectAccessControl or BucketAccessControl

    Returns:
      ACL JSON string.
    """
    serializable_acl = []
    if acl is not None:
      for acl_entry in acl:
        if acl_entry.kind == u'storage#objectAccessControl':
          acl_entry.object = None
          acl_entry.generation = None
        acl_entry.kind = None
        acl_entry.bucket = None
        acl_entry.id = None
        acl_entry.selfLink = None
        acl_entry.etag = None
        serializable_acl.append(encoding.MessageToDict(acl_entry))
    return json.dumps(serializable_acl, sort_keys=True,
                      indent=2, separators=(',', ': '))
