_E='pod_name'
_D='max_version'
_C='presigned_urls'
_B=True
_A=False
import json,logging
from abc import ABC,abstractmethod
from dataclasses import dataclass
from typing import Dict,List,Optional,Set,Tuple
from localstack import constants
from localstack.utils.files import new_tmp_file
from localstack.utils.http import download,safe_requests
from localstack.utils.objects import get_all_subclasses
from localstack.utils.strings import to_str
from requests import Response
from localstack_ext.bootstrap import licensing
from localstack_ext.bootstrap.pods.client_api import CloudPodPreSignedUrls,CloudPodsClientApi
from localstack_ext.bootstrap.pods.utils.common import PodsConfigContext
LOG=logging.getLogger(__name__)
@dataclass
class RemoteConfig:remote_url:str
class CloudPodsRemote(ABC):
	config_context:PodsConfigContext;remote_config:RemoteConfig
	def __init__(A,config_context,remote_config):A.remote_config=remote_config;A.pods_api=CloudPodsClientApi(config_context)
	@classmethod
	@abstractmethod
	def protocols(cls):0
	@abstractmethod
	def list_pods(self):0
	@abstractmethod
	def get_max_version(self,pod_name):0
	@abstractmethod
	def pull_versions(self,pod_name,required_versions):0
	@abstractmethod
	def is_registered(self,pod_name):0
	def push_pod(A,pod_name,version,overwrite=_A):0
	def register_remote(A,pod_name,ci_pod=None):0
	def rename_pod(A,current_name,new_name):0
	def delete_pod(A,pod_name):0
	@classmethod
	def get_for_protocol(E,protocol,**C):
		A=protocol;D=get_all_subclasses(CloudPodsRemote)
		for B in D:
			if A in B.protocols():return B(**C)
		raise Exception(f"Unable to find cloud pod remote implementation for protocol '{A}'")
class CloudPodsRemotePlatform(CloudPodsRemote):
	@classmethod
	def protocols(A):return{'platform'}
	def get_max_version(A,pod_name):
		C=A.create_platform_url(pod_name);D=licensing.get_auth_headers();B=safe_requests.get(url=C,headers=D);E='Failed to get version information from platform.. aborting'
		if not A._check_response(B,message=E,raise_error=_B):return
		F=json.loads(B.content);G=int(F[_D]);return G
	def pull_versions(A,pod_name,required_versions):
		C=','.join((str(A)for A in required_versions));D=A.create_platform_url(f"{pod_name}/data?versions={C}");E=licensing.get_auth_headers();B=safe_requests.get(url=D,headers=E);F='Failed to pull requested versions from platform (code <status_code>)'
		if not A._check_response(B,message=F,raise_error=_B):return
		G=json.loads(B.content);H,I,I=A._prepare_archives_from_pre_signed_urls(G.get(_C));A.pods_api.merge_from_remote(version_space_archive=H)
	def push_pod(A,pod_name,version,overwrite=_A):
		B=A.create_platform_url(f"{pod_name}/data?version={version}")
		if overwrite:B+='&overwrite=true'
		D=licensing.get_auth_headers();C=safe_requests.post(url=B,headers=D);E='Failed to get pre-signed URLs to upload new version: <content> (status <status_code>)'
		if not A._check_response(C,message=E,raise_error=_B):return
		F=json.loads(C.content);G=F.get(_C);A.pods_api.upload_pod_to_pre_signed_urls(pre_signed_urls=G)
	def list_pods(A):C=licensing.get_auth_headers();D=A.create_platform_url();B=safe_requests.get(D,headers=C);A._check_response(B,message='Error fetching list of pods from API (status <status_code>)',raise_error=_B);E=json.loads(B.content);return E
	def delete_pod(A,pod_name):B=A.create_platform_url(pod_name);C=licensing.get_auth_headers();D=safe_requests.delete(url=B,headers=C);return D.ok
	def is_registered(G,pod_name):
		A=pod_name
		try:C=CloudPodsRemotePlatform.create_platform_url();D=licensing.get_auth_headers();B=safe_requests.get(C,headers=D)
		except Exception as E:LOG.debug('An error occurred while checking remote management for pod "%s": "%s"',A,E);return _A
		if not B.ok:return _A
		F=json.loads(B.content);return A in[A[_E]for A in F]
	def register_remote(A,pod_name,ci_pod=None):
		B=pod_name;E=A.pods_api.get_max_version_no();F=licensing.get_auth_headers();G=A.create_platform_url(B);C={_E:B,_D:E,'ci_pod':ci_pod};C=json.dumps(C);D=safe_requests.put(G,C,headers=F);H=f"Failed to register pod {B}: <content>"
		if not A._check_response(D,message=H):return _A
		I=json.loads(D.content);J=I.get(_C);A.pods_api.upload_pod_to_pre_signed_urls(pre_signed_urls=J);return _B
	def rename_pod(B,current_name,new_name):D=new_name;C=current_name;E=licensing.get_auth_headers();F=B.create_platform_url(f"{C}/rename");A={'new_pod_name':D};A=json.dumps(A);G=safe_requests.put(F,A,headers=E);H=f"Failed to rename {C} to {D}: <content>";return B._check_response(G,message=H)
	@staticmethod
	def create_platform_url(path=None):
		A=path;B=f"{constants.API_ENDPOINT}/cloudpods"
		if not A:return B
		A=A if A.startswith('/')else f"/{A}";return f"{B}{A}"
	@classmethod
	def _check_response(C,response,message,raise_error=_A):
		B=response;A=message
		if B.ok:return _B
		if B.status_code in[401,403]:raise Exception('Access denied - please log in first.')
		A=A.replace('<content>',to_str(B.content));A=A.replace('<status_code>',str(B.status_code))
		if raise_error:raise Exception(A)
		LOG.warning(A);return _A
	@staticmethod
	def _prepare_archives_from_pre_signed_urls(pre_signed_urls):A=pre_signed_urls;B=new_tmp_file();E=A.get('versions_archive_url');download(url=E,path=B);C=new_tmp_file();F=A.get('state_archive_url');download(url=F,path=C);D=new_tmp_file();G=A.get('metadata_archive_url');download(url=G,path=D);return B,C,D