# objects.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors
#
# This module is part of GitPython and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
""" Module containing all object based types. """
import base
from git.util import RepoAliasMixin
from git.util import hex_to_bin
from util import (
					get_object_type_by_name,
					parse_actor_and_date
				)
from git.typ import ObjectType

__all__ = ("TagObject", )

class TagObject(base.Object, RepoAliasMixin):
	"""Non-Lightweight tag carrying additional information about an object we are pointing to."""
	type = ObjectType.tag
	type_id = ObjectType.tag_id
	
	__slots__ = ( "object", "tag", "tagger", "tagged_date", "tagger_tz_offset", "message" )
		
	def __init__(self, odb, binsha, object=None, tag=None, 
				tagger=None, tagged_date=None, tagger_tz_offset=None, message=None):
		"""Initialize a tag object with additional data
		
		:param odb: repository this object is located in
		:param binsha: 20 byte SHA1
		:param object: Object instance of object we are pointing to
		:param tag: name of this tag
		:param tagger: Actor identifying the tagger
		:param tagged_date: int_seconds_since_epoch
			is the DateTime of the tag creation - use time.gmtime to convert 
			it into a different format
		:param tagged_tz_offset: int_seconds_west_of_utc is the timezone that the 
			authored_date is in, in a format similar to time.altzone"""
		super(TagObject, self).__init__(odb, binsha )
		if object is not None:
			self.object = object
		if tag is not None:
			self.tag = tag
		if tagger is not None:
			self.tagger = tagger
		if tagged_date is not None:
			self.tagged_date = tagged_date
		if tagger_tz_offset is not None:
			self.tagger_tz_offset = tagger_tz_offset
		if message is not None:
			self.message = message
		
	def _set_cache_(self, attr):
		"""Cache all our attributes at once"""
		if attr in TagObject.__slots__:
			ostream = self.odb.stream(self.binsha)
			lines = ostream.read().splitlines()
			
			obj, hexsha = lines[0].split(" ")		# object <hexsha>
			type_token, type_name = lines[1].split(" ") # type <type_name>
			self.object = get_object_type_by_name(type_name)(self.odb, hex_to_bin(hexsha))
			
			self.tag = lines[2][4:]	 # tag <tag name>
			
			tagger_info = lines[3][7:]# tagger <actor> <date>
			self.tagger, self.tagged_date, self.tagger_tz_offset = parse_actor_and_date(tagger_info)
			
			# line 4 empty - it could mark the beginning of the next header
			# in case there really is no message, it would not exist. Otherwise 
			# a newline separates header from message
			if len(lines) > 5:
				self.message = "\n".join(lines[5:])
			else:
				self.message = ''
		# END check our attributes
		else:
			super(TagObject, self)._set_cache_(attr)
		
		

