class GithubAppInstallation(models.Model):
    """
    This model takes care of the Github installations.
    """
    class InstallationState(models.TextChoices):
        INSTALLED = "INSTALLED", "Installed"
        UNINSTALLED = "UNINSTALLED", "Uninstalled"
    installation_id = models.BigIntegerField(unique=True, db_index=True)
    creator = models.ForeignKey(GithubUser, on_delete=models.PROTECT)
    state = models.CharField(max_length=20, choices=InstallationState.choices)
    account_name = models.CharField(max_length=200)
    account_id = models.BigIntegerField()
    account_type = models.CharField(max_length=20)
    avatar_url = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self) -> str:
        return f"{self.account_name}[{self.installation_id}] Owner: {self.creator.account_name}"
    @property
    def access_token(self):
        try:
            return (
                self.tokens.exclude(expires_at__lte=timezone.now())
                .latest("created_at")
                .token
            )
        except GithubInstallationToken.DoesNotExist:
            self.update_token()
            return self.get_latest_active_token()
    def update_token(self):
        """
        Fetches the latest access token for the installation. Returns true/false depending on whether
        the requested token has been updated
        """
        # User token not required for this step
        github_installation_manager = lib.GithubInstallationManager(
            installation_id=self.installation_id, user_token=""
        )
        token, expires_at = github_installation_manager.get_installation_access_token()
        return GithubInstallationToken.objects.get_or_create(
            token=token,
            expires_at=expires_at,
            github_app_installation=self,
        )[1]
class GithubAppInstallation(models.Model):
    """
    This model takes care of the Github installations.
    """
    class InstallationState(models.TextChoices):
        INSTALLED = "INSTALLED", "Installed"
        UNINSTALLED = "UNINSTALLED", "Uninstalled"
    installation_id = models.BigIntegerField(unique=True, db_index=True)
    creator = models.ForeignKey(GithubUser, on_delete=models.PROTECT)
    state = models.CharField(max_length=20, choices=InstallationState.choices)
    account_name = models.CharField(max_length=200)
    account_id = models.BigIntegerField()
    account_type = models.CharField(max_length=20)
    avatar_url = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self) -> str:
        return f"{self.account_name}[{self.installation_id}] Owner: {self.creator.account_name}"
    @property
    def access_token(self):
        try:
            return (
                self.tokens.exclude(expires_at__lte=timezone.now())
                .latest("created_at")
                .token
            )
        except GithubInstallationToken.DoesNotExist:
            self.update_token()
            return self.get_latest_active_token()
    def update_token(self):
        """
        Fetches the latest access token for the installation. Returns true/false depending on whether
        the requested token has been updated
        """
        # User token not required for this step
        github_installation_manager = lib.GithubInstallationManager(
            installation_id=self.installation_id, user_token=""
        )
        token, expires_at = github_installation_manager.get_installation_access_token()
        return GithubInstallationToken.objects.get_or_create(
            token=token,
            expires_at=expires_at,
            github_app_installation=self,
        )[1]