# Path: libcloudforensics/errors.py
# class LCFError(Exception):
# class CredentialsConfigurationError(LCFError):
# class InvalidFileFormatError(LCFError):
# class InvalidNameError(LCFError):
# class ResourceNotFoundError(LCFError):
# class ResourceCreationError(LCFError):
# class ResourceDeletionError(LCFError):
# class InstanceStateChangeError(LCFError):
# class ServiceAccountRemovalError(LCFError):
# class InstanceProfileCreationError(LCFError):
# class OperationFailedError(LCFError):
# class TransferCreationError(LCFError):
# class TransferExecutionError(LCFError):
# class ResourceAlreadyExistsError(LCFError):
#   def __init__(self,
#                message: str,
#                name: str) -> None:
# 
# Path: libcloudforensics/logging_utils.py
# def _GenerateColorSequences() -> List[str]:
#   def __init__(self,
#                colorize: bool = True,
#                random_color: bool = False,
#                **kwargs: str) -> None:
#   def format(self, record: logging.LogRecord) -> str:
# def SetUpLogger(name: str, no_newline: bool = False) -> None:
# def GetLogger(name: str) -> logging.Logger:
# COLOR_SEQS = _GenerateColorSequences()
# RESET_SEQ = '\u001b[0m'
# BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = COLOR_SEQS[8:16]
# BG_RED = '\u001b[41m'  # Red background
# BOLD = '\u001b[1m'  # Bold / bright modifier
# LOG_FORMAT = ('[%(asctime)s] [{0:s}{color:s}%(name)-20s{1:s}] %(levelname)-8s'
#               ' %(message)s')
# LEVEL_COLOR_MAP = {
#     'WARNING': YELLOW,
#     'INFO': WHITE,
#     'DEBUG': BLUE,
#     'CRITICAL': BOLD + BG_RED + WHITE,
#     'ERROR': RED
# }
# class Formatter(logging.Formatter):
# 
# Path: libcloudforensics/providers/aws/internal/common.py
# EC2_SERVICE = 'ec2'
# ACCOUNT_SERVICE = 'sts'
# KMS_SERVICE = 'kms'
# CLOUDTRAIL_SERVICE = 'cloudtrail'
# S3_SERVICE = 's3'
# IAM_SERVICE = 'iam'
# INSTANCE = 'instance'
# VOLUME = 'volume'
# SNAPSHOT = 'snapshot'
# UBUNTU_1804_FILTER = 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20200611'  # pylint: disable=line-too-long
# ALINUX2_BASE_FILTER = 'amzn2-ami-hvm-2*-x86_64-gp2'
# def CreateTags(resource: str, tags: Dict[str, str]) -> Dict[str, Any]:
# def GetInstanceTypeByCPU(cpu_cores: int) -> str:
# def ExecuteRequest(client: 'botocore.client.EC2',
#                    func: str,
#                    kwargs: Dict[str, Any]) -> List[Dict[str, Any]]:
# 
# Path: libcloudforensics/providers/gcp/internal/storage.py
# class GoogleCloudStorage:
#   CLOUD_STORAGE_API_VERSION = 'v1'
#   def __init__(self, project_id: Optional[str] = None) -> None:
#   def GcsApi(self) -> 'googleapiclient.discovery.Resource':
#   def GetObjectMetadata(self,
#                         gcs_path: str,
#                         user_project: Optional[str] = None) -> Dict[str, Any]:
#   def GetBucketACLs(self,
#                     bucket: str,
#                     user_project: Optional[str] = None) -> Dict[str, List[str]]:
#   def ListBuckets(self) -> List[Dict[str, Any]]:
#   def ListBucketObjects(self, bucket: str) -> List[Dict[str, Any]]:
#   def DeleteObject(self, gcs_path: str) -> None:
#   def GetBucketSize(self,
#                     bucket: str,
#                     timeframe: int = 1) -> Dict[str, int]:
#   def CreateBucket(
#       self,
#       bucket: str,
#       labels: Optional[Dict[str, str]] = None,
#       predefined_acl: str = 'private',
#       predefined_default_object_acl: str = 'private') -> Dict[str, Any]:
#   def GetObject(self,
#                 gcs_path: str,
#                 out_file: Optional[str] = None) -> str:
# 
# Path: libcloudforensics/providers/utils/storage_utils.py
# def SplitStoragePath(path: str) -> Tuple[str, str]:
#   """Split a path to bucket name and object URI.
# 
#   Args:
#     path (str): File path to a resource in GCS.
#         Ex: gs://bucket/folder/obj
# 
#   Returns:
#     Tuple[str, str]: Bucket name. Object URI.
#   """
# 
#   _, _, full_path = path.partition('//')
#   bucket, _, object_uri = full_path.partition('/')
#   return bucket, object_uri


import os
from typing import TYPE_CHECKING, List, Dict, Optional, Any
from libcloudforensics import errors
from libcloudforensics import logging_utils
from libcloudforensics.providers.aws.internal import common
from libcloudforensics.providers.gcp.internal import storage as gcp_storage
from libcloudforensics.providers.utils.storage_utils import SplitStoragePath
  from libcloudforensics.providers.aws.internal import account  # pylint: disable=cyclic-import

  def RmObjectByPath(
      self,
      s3_path: str
    ) -> None:
    """Remove an object from S3.

    Args:
      s3_path (str): The path of the object to remove.
    """
    if not s3_path.startswith('s3://'):
      s3_path = 's3://' + s3_path
    bucket, key = SplitStoragePath(s3_path)

    self.RmObject(bucket, key)

  def RmObject(
      self,
      bucket: str,
      key: str
    ) -> None:
    """Remove an object from S3.

    Args:
      bucket (str): The S3 bucket.
      key (str): The object key (path).
    """
    if key.startswith('/'):
      key = key.lstrip('/')


# Path: libcloudforensics/errors.py
# class LCFError(Exception):
# class CredentialsConfigurationError(LCFError):
# class InvalidFileFormatError(LCFError):
# class InvalidNameError(LCFError):
# class ResourceNotFoundError(LCFError):
# class ResourceCreationError(LCFError):
# class ResourceDeletionError(LCFError):
# class InstanceStateChangeError(LCFError):
# class ServiceAccountRemovalError(LCFError):
# class InstanceProfileCreationError(LCFError):
# class OperationFailedError(LCFError):
# class TransferCreationError(LCFError):
# class TransferExecutionError(LCFError):
# class ResourceAlreadyExistsError(LCFError):
#   def __init__(self,
#                message: str,
#                name: str) -> None:
# 
# Path: libcloudforensics/logging_utils.py
# def _GenerateColorSequences() -> List[str]:
#   def __init__(self,
#                colorize: bool = True,
#                random_color: bool = False,
#                **kwargs: str) -> None:
#   def format(self, record: logging.LogRecord) -> str:
# def SetUpLogger(name: str, no_newline: bool = False) -> None:
# def GetLogger(name: str) -> logging.Logger:
# COLOR_SEQS = _GenerateColorSequences()
# RESET_SEQ = '\u001b[0m'
# BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = COLOR_SEQS[8:16]
# BG_RED = '\u001b[41m'  # Red background
# BOLD = '\u001b[1m'  # Bold / bright modifier
# LOG_FORMAT = ('[%(asctime)s] [{0:s}{color:s}%(name)-20s{1:s}] %(levelname)-8s'
#               ' %(message)s')
# LEVEL_COLOR_MAP = {
#     'WARNING': YELLOW,
#     'INFO': WHITE,
#     'DEBUG': BLUE,
#     'CRITICAL': BOLD + BG_RED + WHITE,
#     'ERROR': RED
# }
# class Formatter(logging.Formatter):
# 
# Path: libcloudforensics/providers/aws/internal/common.py
# EC2_SERVICE = 'ec2'
# ACCOUNT_SERVICE = 'sts'
# KMS_SERVICE = 'kms'
# CLOUDTRAIL_SERVICE = 'cloudtrail'
# S3_SERVICE = 's3'
# IAM_SERVICE = 'iam'
# INSTANCE = 'instance'
# VOLUME = 'volume'
# SNAPSHOT = 'snapshot'
# UBUNTU_1804_FILTER = 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20200611'  # pylint: disable=line-too-long
# ALINUX2_BASE_FILTER = 'amzn2-ami-hvm-2*-x86_64-gp2'
# def CreateTags(resource: str, tags: Dict[str, str]) -> Dict[str, Any]:
# def GetInstanceTypeByCPU(cpu_cores: int) -> str:
# def ExecuteRequest(client: 'botocore.client.EC2',
#                    func: str,
#                    kwargs: Dict[str, Any]) -> List[Dict[str, Any]]:
# 
# Path: libcloudforensics/providers/gcp/internal/storage.py
# class GoogleCloudStorage:
#   CLOUD_STORAGE_API_VERSION = 'v1'
#   def __init__(self, project_id: Optional[str] = None) -> None:
#   def GcsApi(self) -> 'googleapiclient.discovery.Resource':
#   def GetObjectMetadata(self,
#                         gcs_path: str,
#                         user_project: Optional[str] = None) -> Dict[str, Any]:
#   def GetBucketACLs(self,
#                     bucket: str,
#                     user_project: Optional[str] = None) -> Dict[str, List[str]]:
#   def ListBuckets(self) -> List[Dict[str, Any]]:
#   def ListBucketObjects(self, bucket: str) -> List[Dict[str, Any]]:
#   def DeleteObject(self, gcs_path: str) -> None:
#   def GetBucketSize(self,
#                     bucket: str,
#                     timeframe: int = 1) -> Dict[str, int]:
#   def CreateBucket(
#       self,
#       bucket: str,
#       labels: Optional[Dict[str, str]] = None,
#       predefined_acl: str = 'private',
#       predefined_default_object_acl: str = 'private') -> Dict[str, Any]:
#   def GetObject(self,
#                 gcs_path: str,
#                 out_file: Optional[str] = None) -> str:
# 
# Path: libcloudforensics/providers/utils/storage_utils.py
# def SplitStoragePath(path: str) -> Tuple[str, str]:
#   """Split a path to bucket name and object URI.
# 
#   Args:
#     path (str): File path to a resource in GCS.
#         Ex: gs://bucket/folder/obj
# 
#   Returns:
#     Tuple[str, str]: Bucket name. Object URI.
#   """
# 
#   _, _, full_path = path.partition('//')
#   bucket, _, object_uri = full_path.partition('/')
#   return bucket, object_uri


# Path: libcloudforensics/providers/aws/internal/s3.py
import os
from typing import TYPE_CHECKING, List, Dict, Optional, Any
from libcloudforensics import errors
from libcloudforensics import logging_utils
from libcloudforensics.providers.aws.internal import common
from libcloudforensics.providers.gcp.internal import storage as gcp_storage
from libcloudforensics.providers.utils.storage_utils import SplitStoragePath
  from libcloudforensics.providers.aws.internal import account  # pylint: disable=cyclic-import


  def RmObjectByPath(
      self,
      s3_path: str
    ) -> None:
    """Remove an object from S3.

    Args:
      s3_path (str): The path of the object to remove.
    """
    if not s3_path.startswith('s3://'):
      s3_path = 's3://' + s3_path
    bucket, key = SplitStoragePath(s3_path)

    self.RmObject(bucket, key)

  def RmObject(
      self,
      bucket: str,
      key: str
    ) -> None:
    """Remove an object from S3.

    Args:
      bucket (str): The S3 bucket.
      key (str): The object key (path).
    """
    if key.startswith('/'):
      key = key.lstrip('/')


    s3_client = self.aws_account.ClientApi(common.S3_SERVICE)