import requests
import json
import jwt
import os
import logging

logging.basicConfig(level=logging.INFO)
class Authorization:
    def __init__(self, key):
        self.key = key
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.key}"
        }

        # check Authorization


class CloudAuthorization:
    def __init__(self):
        self.META_DATA_URL = "http://metadata.google.internal/computeMetadata/v1/"
        self.META_DATA_HEADER ={"Metadata-Flavor": "Google"}
        self.service_url = "https://run.googleapis.com/v1/projects/customer-360-profile/locations/asia-southeast1/services/ydm-profile-360"

    def get_access_token(self):
        url = f'''{self.META_DATA_URL}instance/service-accounts/default/token'''
        r = requests.get(url, headers=self.META_DATA_HEADER)
        access_token = r.json()["access_token"]
        return access_token

    def get_cloud_run_service_info(self, access_token=None):
        if access_token is None:
            return None
           
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json"
        }
        response = requests.get(self.service_url, headers=headers)
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"Failed to get service info: {response.status_code} - {response.text}")
        
    def add_cloud_run_service_env_var(self, access_token=None,info=None, env_pack=None):
        if info is None:
            raise ValueError("info is None")
        if env_pack is None:
            raise ValueError("env_pack is None")
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json"
        }
        
        old_env = list(info.get("spec").get("template").get("spec").get("containers")[0].get("env"))

        # env_pack is a dict and contain new var
        for env in env_pack:
            if env.get("name") not in [e.get("name") for e in old_env]:
                old_env.append(env)

        info.get("spec").get("template").get("spec").get("containers")[0]["env"] = old_env

        response = requests.put(self.service_url, headers=headers, json=info)

        return response
    
    def update_cloud_run_service_env_var(self, access_token=None,info=None, env_updates=None):
        if info is None:
            raise ValueError("info is None")
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json"
        }
        current_env_vars = info.get("spec", {}).get("template", {}).get("spec", {}).get("containers", [])[0].get("env", [])
        
        updated_env_list = []
        env_names_to_update = set(env_updates.keys())
        
        for env_var in current_env_vars:
            if env_var["name"] in env_names_to_update:
                # If the variable exists and is in our update list, append the new value
                new_value_to_add = env_updates[env_var["name"]]
                if env_var.get("value"):
                    # Append with a comma if there's an existing value
                    env_var["value"] = f"{env_var['value']},{new_value_to_add}"
                else:
                    # If no existing value, just set it
                    env_var["value"] = new_value_to_add
                env_names_to_update.remove(env_var["name"]) # Mark as updated
            updated_env_list.append(env_var)
        
        for env_name in env_names_to_update:
            updated_env_list.append({"name": env_name, "value": env_updates[env_name]})

        info["spec"]["template"]["spec"]["containers"][0]["env"] = updated_env_list
        response = requests.put(self.service_url, headers=headers, json=info)
        return response
    

class TokenAuthorization:
    def __init__(self, access_token):
        self.access_token = access_token
        self.token = os.environ.get("TOKEN_GENERATE")

    def validate(self, algorithm="HS256"):
        try:
            decoded = jwt.decode(self.access_token, self.token, algorithms=[algorithm])
            return decoded
        except jwt.ExpiredSignatureError:
            logging.error("Token has expired")
            return False
        except jwt.InvalidTokenError:
            logging.error("Token invalid")
            return False
        
    def get_user_id(self):
        try:
            decoded = self.validate()
            user_id = decoded['user_id']
            return user_id
        except jwt.ExpiredSignatureError:
            logging.error("Token has expired")
            return False
        except jwt.InvalidTokenError:
            logging.error("Token invalid")
            return False