#    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 atlas_client.client import Atlas
from atlas_s3_hook.S3Hook import S3Hook
from atlas_s3_hook.S3MetadataClient import S3MetadataClient
from atlas_s3_hook.S3PathClass import S3PathClass


class S3Scanner:
    def __init__(self, s3_client: S3MetadataClient, atlas_client: Atlas, owner="unknown") -> None:
        self.s3_client = s3_client
        self.fs = s3_client.get_fs()
        self.default_owner = owner
        self.s3_atlas_hook = S3Hook(s3_client, atlas_client)

    def scan_path(self, path: str, description: str = "generated by s3 atlas hook") -> None:
        sub_path_list = self.fs.ls(path)
        for sub_path in sub_path_list:
            path_class = self.s3_client.get_class_from_path(sub_path)
            current_path_meta = self.s3_client.get_path_meta_data(sub_path)
            if path_class == S3PathClass.BUCKET:
                self.s3_atlas_hook.create_atlas_bucket(current_path_meta, description)
                # call dir scanner recursively
                self.scan_path(sub_path)
            elif path_class == S3PathClass.DIR:
                self.s3_atlas_hook.create_atlas_ps_dir(current_path_meta, description)
                self.scan_path(sub_path)
            elif path_class == S3PathClass.OBJECT:
                # avoid loading .keep file
                if sub_path.split("/")[-1] == ".keep":
                    pass
                else:
                    self.s3_atlas_hook.create_atlas_object(current_path_meta, self.default_owner, description)
            else:
                raise ValueError
