# #####################################################################################################################
#  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.                                                 #
#                                                                                                                     #
#  Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance     #
#  with the License. You may obtain a copy of the License at                                                          #
#                                                                                                                     #
#   http://www.apache.org/licenses/LICENSE-2.0                                                                        #
#                                                                                                                     #
#  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed   #
#  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for  #
#  the specific language governing permissions and limitations under the License.                                     #
# #####################################################################################################################

from urllib.parse import unquote_plus
from uuid import uuid4

from packaging import version

from shared.Dataset.dataset_file import DatasetFile
from shared.s3.exceptions import (
    RecordNotFound,
    RecordNotSupported,
    BucketNotFound,
    KeyNotFound,
)

S3_EVENT_STRUCTURE_MAJOR = 2


class Event:
    def __init__(self, event):
        self.uuid = f"{uuid4().time_low:x}"
        self.bucket, self.key, self.file = self.validate(event)

    def validate(self, event: dict):
        record = next(iter(event.get("Records", [{}])))
        if not record:
            raise RecordNotFound

        # Make sure this event version is supported
        event_version = record.get("eventVersion")
        if version.parse(event_version).major != S3_EVENT_STRUCTURE_MAJOR:
            raise RecordNotSupported(
                f"The event version {event_version} is not supported by this solution."
            )

        # Make sure there's a bucket in the event structure
        bucket = record.get("s3", {}).get("bucket", {}).get("name")
        if not bucket:
            raise BucketNotFound

        # Make sure there's a key in the event structure
        key = unquote_plus(
            record.get("s3", {}).get("object", {}).get("key", ""), "utf-8"
        )

        if not key:
            raise KeyNotFound

        # The name of the event is the stem of the file without extensions
        file = DatasetFile(key=key, bucket=bucket)

        return bucket, key, file

    @property
    def event_id(self) -> str:
        return f"{self.file.prefix}_{str(self.file.data_type).lower()}_{self.uuid}"[
            0:80
        ]