// Copyright (c) The Thanos Authors.
// Licensed under the Apache License 2.0.

package objstore

import (
	
	
	
)

type PrefixedBucket struct {
	bkt    Bucket
	prefix string
}

func ( Bucket,  string) Bucket {
	if validPrefix() {
		return &PrefixedBucket{bkt: , prefix: strings.Trim(, DirDelim)}
	}

	return 
}

func validPrefix( string) bool {
	 = strings.Replace(, "/", "", -1)
	return len() > 0
}

func conditionalPrefix(,  string) string {
	if len() > 0 {
		return withPrefix(, )
	}

	return 
}

func withPrefix(,  string) string {
	return  + DirDelim + 
}

func ( *PrefixedBucket) () error {
	return .bkt.Close()
}

// Iter calls f for each entry in the given directory (not recursive.). The argument to f is the full
// object name including the prefix of the inspected directory.
// Entries are passed to function in sorted order.
func ( *PrefixedBucket) ( context.Context,  string,  func(string) error,  ...IterOption) error {
	 := withPrefix(.prefix, )

	return .bkt.Iter(, , func( string) error {
		return (strings.TrimPrefix(, .prefix+DirDelim))
	}, ...)
}

// Get returns a reader for the given object name.
func ( *PrefixedBucket) ( context.Context,  string) (io.ReadCloser, error) {
	return .bkt.Get(, conditionalPrefix(.prefix, ))
}

// GetRange returns a new range reader for the given object name and range.
func ( *PrefixedBucket) ( context.Context,  string,  int64,  int64) (io.ReadCloser, error) {
	return .bkt.GetRange(, conditionalPrefix(.prefix, ), , )
}

// Exists checks if the given object exists in the bucket.
func ( *PrefixedBucket) ( context.Context,  string) (bool, error) {
	return .bkt.Exists(, conditionalPrefix(.prefix, ))
}

// IsObjNotFoundErr returns true if error means that object is not found. Relevant to Get operations.
func ( *PrefixedBucket) ( error) bool {
	return .bkt.IsObjNotFoundErr()
}

// IsAccessDeniedErr returns true if access to object is denied.
func ( *PrefixedBucket) ( error) bool {
	return .bkt.IsAccessDeniedErr()
}

// Attributes returns information about the specified object.
func ( PrefixedBucket) ( context.Context,  string) (ObjectAttributes, error) {
	return .bkt.Attributes(, conditionalPrefix(.prefix, ))
}

// Upload the contents of the reader as an object into the bucket.
// Upload should be idempotent.
func ( *PrefixedBucket) ( context.Context,  string,  io.Reader) error {
	return .bkt.Upload(, conditionalPrefix(.prefix, ), )
}

// Delete removes the object with the given name.
// If object does not exists in the moment of deletion, Delete should throw error.
func ( *PrefixedBucket) ( context.Context,  string) error {
	return .bkt.Delete(, conditionalPrefix(.prefix, ))
}

// Name returns the bucket name for the provider.
func ( *PrefixedBucket) () string {
	return .bkt.Name()
}