import datetime
import logging
import re
from urllib.error import HTTPError


class OBSRevision:
    def __init__(self, obs, project, package):
        self.obs = obs
        self.project = project
        self.package = package

        self.commit = None
        self.ignored = False

    def parse(self, xml):
        self.rev = int(xml.get("rev"))
        self.unexpanded_srcmd5 = xml.find("srcmd5").text
        # Replaced in check_expanded
        self.srcmd5 = self.unexpanded_srcmd5

        time = int(xml.find("time").text)
        self.time = datetime.datetime.fromtimestamp(time)

        userid = xml.find("user")
        if userid is not None:
            self.userid = userid.text
        else:
            self.userid = "unknown"

        comment = xml.find("comment")
        if comment is not None:
            self.comment = comment.text or ""
        else:
            self.comment = ""

        # Populated by check_link
        self.linkrev = None

        self.request_number = None
        request_number = xml.find("requestid")
        if request_number is not None:
            self.request_number = int(request_number.text)
        else:
            # Sometimes requestid is missing, but can be extracted
            # from "comment"
            matched = re.match(
                r"^Copy from .* based on submit request (\d+) from user .*$",
                self.comment,
            )
            if matched:
                self.request_number = int(matched.group(1))

        return self

    def __str__(self):
        return f"Rev {self.project}/{self.package}/{self.rev}.0 Md5 {self.srcmd5} {self.time} {self.userid} {self.request_number}"

    def __repr__(self):
        return f"[{self.__str__()}]"

    def read_link(self):
        try:
            return self.obs._xml(
                f"source/{self.project}/{self.package}/_link",
                rev=self.unexpanded_srcmd5,
            )
        except HTTPError as e:
            if e.code == 404:
                logging.debug("No _link for the revision")
                return None
            raise e