
# Copyright 2011 Google Inc. All Rights Reserved.

import os
import threading

from cros_utils import logger
from cros_utils.file_utils import FileUtils


class ImageChecksummer(object):

  class PerImageChecksummer(object):

    def __init__(self, label, log_level):
      self._lock = threading.Lock()
      self.label = label
      self._checksum = None
      self.log_level = log_level

    def Checksum(self):
      with self._lock:
        if not self._checksum:
          logger.GetLogger().LogOutput("Acquiring checksum for '%s'." %
                                       self.label.name)
          self._checksum = None
          if self.label.image_type != 'local':
            raise Exception('Called Checksum on non-local image!')
          if self.label.chromeos_image:
            if os.path.exists(self.label.chromeos_image):
              self._checksum = FileUtils().Md5File(self.label.chromeos_image,
                                                   log_level=self.log_level)
              logger.GetLogger().LogOutput('Computed checksum is '
                                           ': %s' % self._checksum)
          if not self._checksum:
            raise Exception('Checksum computing error.')
          logger.GetLogger().LogOutput('Checksum is: %s' % self._checksum)
        return self._checksum

  _instance = None
  _lock = threading.Lock()
  _per_image_checksummers = {}

  def __new__(cls, *args, **kwargs):
    with cls._lock:
      if not cls._instance:
        cls._instance = super(ImageChecksummer, cls).__new__(cls, *args,
                                                             **kwargs)
      return cls._instance

  def Checksum(self, label, log_level):
    if label.image_type != 'local':
      raise Exception('Attempt to call Checksum on non-local image.')
    with self._lock:
      if label.name not in self._per_image_checksummers:
        self._per_image_checksummers[label.name] = (
            ImageChecksummer.PerImageChecksummer(label, log_level))
      checksummer = self._per_image_checksummers[label.name]

    try:
      return checksummer.Checksum()
    except Exception, e:
      logger.GetLogger().LogError('Could not compute checksum of image in label'
                                  " '%s'." % label.name)
      raise e
