# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import base64
import os
import re


class Image(object):

  def __init__(self, resource):
    self.resource = resource
    self.aliases = []

  @property
  def relative_path(self):
    return self.resource.relative_path

  @property
  def absolute_path(self):
    return self.resource.absolute_path

  @property
  def contents(self):
    return self.resource.contents


class ParsedStyleSheet(object):

  def __init__(self, loader, containing_dirname, contents):
    self.loader = loader
    self.contents = contents
    self._images = None
    self._Load(containing_dirname)

  @property
  def images(self):
    return self._images

  def AppendDirectlyDependentFilenamesTo(self, dependent_filenames):
    for i in self.images:
      dependent_filenames.append(i.resource.absolute_path)

  @property
  def contents_with_inlined_images(self):
    images_by_url = {}
    for i in self.images:
      for a in i.aliases:
        images_by_url[a] = i

    def InlineUrl(m):
      url = m.group('url')
      image = images_by_url[url]

      ext = os.path.splitext(image.absolute_path)[1]
      data = base64.standard_b64encode(image.contents)

      return 'url(data:image/%s;base64,%s)' % (ext[1:], data)

    # I'm assuming we only have url()'s associated with images
    return re.sub('url\((?P<quote>"|\'|)(?P<url>[^"\'()]*)(?P=quote)\)',
                  InlineUrl, self.contents)

  def AppendDirectlyDependentFilenamesTo(self, dependent_filenames):
    for i in self.images:
      dependent_filenames.append(i.resource.absolute_path)

  def _Load(self, containing_dirname):
    if self.contents.find('@import') != -1:
      raise Exception('@imports are not supported')

    matches = re.findall(
        'url\((?:["|\']?)([^"\'()]*)(?:["|\']?)\)',
        self.contents)

    def resolve_url(url):
      if os.path.isabs(url):
        # FIXME: module is used here, but py_vulcanize.module is never imported.
        # However, py_vulcanize.module cannot be imported since py_vulcanize.module may import
        # style_sheet, leading to an import loop.
        raise module.DepsException('URL references must be relative')
      # URLS are relative to this module's directory
      abs_path = os.path.abspath(os.path.join(containing_dirname, url))
      image = self.loader.LoadImage(abs_path)
      image.aliases.append(url)
      return image

    self._images = [resolve_url(x) for x in matches]


class StyleSheet(object):
  """Represents a stylesheet resource referenced by a module via the
  base.requireStylesheet(xxx) directive."""

  def __init__(self, loader, name, resource):
    self.loader = loader
    self.name = name
    self.resource = resource
    self._parsed_style_sheet = None

  @property
  def filename(self):
    return self.resource.absolute_path

  @property
  def contents(self):
    return self.resource.contents

  def __repr__(self):
    return 'StyleSheet(%s)' % self.name

  @property
  def images(self):
    self._InitParsedStyleSheetIfNeeded()
    return self._parsed_style_sheet.images

  def AppendDirectlyDependentFilenamesTo(self, dependent_filenames):
    self._InitParsedStyleSheetIfNeeded()

    dependent_filenames.append(self.resource.absolute_path)
    self._parsed_style_sheet.AppendDirectlyDependentFilenamesTo(
        dependent_filenames)

  @property
  def contents_with_inlined_images(self):
    self._InitParsedStyleSheetIfNeeded()
    return self._parsed_style_sheet.contents_with_inlined_images

  def load(self):
    self._InitParsedStyleSheetIfNeeded()

  def _InitParsedStyleSheetIfNeeded(self):
    if self._parsed_style_sheet:
      return
    module_dirname = os.path.dirname(self.resource.absolute_path)
    self._parsed_style_sheet = ParsedStyleSheet(
        self.loader, module_dirname, self.contents)
