import simpleplugin
import hashlib

class Tag(object):
    def __init__(self, key = None, value=None):
        self.key = key
        self.value = value

class Field(object):
    def __init__(self, key = None, value=None):
        self.key = key
        self.value = value

class Metric(object):
    def __init__(self, name, tags, fields, tm):
        self.name = name
        self.tags = None
        self.fields = None
        self.tm = tm

        if len(tags) > 0:
            self.tags = []
            for k, v in sorted(tags.items()):
                self.tags.append(Tag(key=k, value=v))

        if len(fields) > 0:
            self.fields = []
            for k, v in fields.items():
                self.addField(k, v)

    def __str__(self):
        return "{} {} {} {}".format(self.name, self.tagsDict(), self.fieldsDict(), int(self.tm))

    def name(self):
        return self.name

    def tagsDict(self):
        tagsDict = {}
        if self.tags:
            for tag in self.tags:
                tagsDict[tag.key] = tag.value
        return tagsDict

    def tagList(self):
        return self.tags

    def fieldsDict(self):
        fieldsDict = {}
        if self.fields:
            for field in self.fields:
                fieldsDict[field.key] = field.value
        return fieldsDict

    def fieldList(self):
        return self.fields

    def time(self):
        return self.tm

    def setName(self, name):
        self.name = name

    def addPrefix(self, prefix):
        self.name = prefix + self.name

    def addSuffix(self, suffix):
        self.name = self.name + suffix

    def addTag(self, key, value):
        for i, tag in enumerate(self.tags):
            if key > tag.key:
                continue

            if key == tag.key:
                tag.value = value
                return

            self.tags.insert(i, Tag(key=key, value=value))
            return

        self.tags.append(Tag(key=key, value=value))

    def hasTag(self, key):
        for tag in self.tags:
            if tag.Key == key:
                return True
        return False

    def getTag(self, key):
        for tag in self.tags:
            if tag.Key == key:
                return tag.Value, True
        return "", False

    def removeTag(self, key):
        for i, tag in enumerate(self.tags):
            if tag.Key == key:
                del self.tags[i]
                return

    def addField(self, key, value):
        for i, field in enumerate(self.fields):
            if key == field.Key:
                self.fields[i] = simpleplugin.Field(Key=key, value=value)
                return

        self.fields.append(simpleplugin.Field(Key=key, value=value))

    def hasField(self, key):
        for field in self.fields:
            if field.Key == key:
                return True
        return False

    def getField(self, key):
        for field in self.fields:
            if field.Key == key:
                return field.Value, True
        return None, False

    def removeField(self, key):
        for i, field in enumerate(self.fields):
            if field.Key == key:
                del self.fields[i]
                return

    def setTime(self, t):
        self.tm = t

    def copy(self):
        m2 = Metric(
            name=self.name,
            tags={tag.key: tag.value for tag in self.tags},
            fields={field.key: field.value for field in self.fields},
            tm=self.tm
        )
        return m2

    def hashId(self):
        h = hashlib.sha256()

        h.update(self.name)
        h.update("\n")
        if self.tags:
            for tag in self.tags:
                h.update(tag.key)
                h.update("\n")
                h.update(tag.value)
                h.update("\n")

        return h.hexdigest()

    def accept(self):
        pass

    def reject(self):
        pass

    def drop(self):
        pass

class LogMetric(Metric):
    def __init__(self, name, tags, fields, content, line, tm):
        super(LogMetric, self).__init__(name, tags, fields, tm)
        self.content = content
        self.line = line

    def __str__(self):
        return "{} {} {} {}".format(self.name, self.tagsDict(), self.fieldsDict(), int(self.tm))

    def content(self):
        return self.content

    def line(self):
        return self.line
