// Code generated by go generate cmd/definitions; DO NOT EDIT.
package types

import (
	"fmt"
	"sync"
	"time"
)

// Field index in object bit
const (
	objectIndexAppendOffset       uint64 = 1 << 0
	objectIndexContentDisposition uint64 = 1 << 1
	objectIndexContentLength      uint64 = 1 << 2
	objectIndexContentMd5         uint64 = 1 << 3
	objectIndexContentType        uint64 = 1 << 4
	objectIndexEtag               uint64 = 1 << 5
	objectIndexID                 uint64 = 1 << 6
	objectIndexLastModified       uint64 = 1 << 7
	objectIndexLinkTarget         uint64 = 1 << 8
	objectIndexMode               uint64 = 1 << 9
	objectIndexMultipartID        uint64 = 1 << 10
	objectIndexPath               uint64 = 1 << 11
	objectIndexSystemMetadata     uint64 = 1 << 12
	objectIndexUserMetadata       uint64 = 1 << 13
)

// Object is the smallest unit in go-storage.
//
// NOTES:
//   - Object's fields SHOULD not be changed outside services.
//   - Object CANNOT be copied
//   - Object is concurrent safe.
//   - Only ID, Path, Mode are required during list operations, other fields
//     could be fetched via lazy stat logic: https://beyondstorage.io/docs/go-storage/internal/object-lazy-stat
type Object struct { // AppendOffset is the offset of the append object.
	appendOffset       int64
	contentDisposition string
	contentLength      int64
	contentMd5         string
	contentType        string
	etag               string
	// ID is the unique key in storage.
	//
	// ID SHOULD be an absolute path compatible with the target operating system-defined file paths,
	// or a unique identifier specified by service.
	ID           string
	lastModified time.Time
	// LinkTarget is the symlink target for link object.
	linkTarget string
	Mode       ObjectMode
	// MultipartID is the part id of part object.
	multipartID string
	// Path is either the absolute path or the relative path towards storage's WorkDir depends on user's
	// input.
	//
	// Path SHOULD be Unix style.
	Path string
	// SystemMetadata stores system defined metadata.
	systemMetadata interface{}
	// UserMetadata stores user defined metadata.
	userMetadata map[string]string
	// client is the client in which Object is alive.
	client Storager
	// bit used as a bitmap for object value, 0 means not set, 1 means set
	bit  uint64
	done uint32
	m    sync.Mutex
}

// GetAppendOffset will get AppendOffset from Object.
//
// AppendOffset is the offset of the append object.
func (o *Object) GetAppendOffset() (int64, bool) {
	o.stat()

	if o.bit&objectIndexAppendOffset != 0 {
		return o.appendOffset, true
	}
	return 0, false
}

// MustGetAppendOffset will get AppendOffset from Object.
//
// AppendOffset is the offset of the append object.
func (o *Object) MustGetAppendOffset() int64 {
	o.stat()

	if o.bit&objectIndexAppendOffset == 0 {
		panic(fmt.Sprintf("object append_offset is not set"))
	}
	return o.appendOffset
}

// SetAppendOffset will get AppendOffset into Object.
//
// AppendOffset is the offset of the append object.
func (o *Object) SetAppendOffset(v int64) *Object {
	o.appendOffset = v
	o.bit |= objectIndexAppendOffset
	return o
}

// GetContentDisposition will get ContentDisposition from Object.
func (o *Object) GetContentDisposition() (string, bool) {
	o.stat()

	if o.bit&objectIndexContentDisposition != 0 {
		return o.contentDisposition, true
	}
	return "", false
}

// MustGetContentDisposition will get ContentDisposition from Object.
func (o *Object) MustGetContentDisposition() string {
	o.stat()

	if o.bit&objectIndexContentDisposition == 0 {
		panic(fmt.Sprintf("object content_disposition is not set"))
	}
	return o.contentDisposition
}

// SetContentDisposition will get ContentDisposition into Object.
func (o *Object) SetContentDisposition(v string) *Object {
	o.contentDisposition = v
	o.bit |= objectIndexContentDisposition
	return o
}

// GetContentLength will get ContentLength from Object.
func (o *Object) GetContentLength() (int64, bool) {
	o.stat()

	if o.bit&objectIndexContentLength != 0 {
		return o.contentLength, true
	}
	return 0, false
}

// MustGetContentLength will get ContentLength from Object.
func (o *Object) MustGetContentLength() int64 {
	o.stat()

	if o.bit&objectIndexContentLength == 0 {
		panic(fmt.Sprintf("object content_length is not set"))
	}
	return o.contentLength
}

// SetContentLength will get ContentLength into Object.
func (o *Object) SetContentLength(v int64) *Object {
	o.contentLength = v
	o.bit |= objectIndexContentLength
	return o
}

// GetContentMd5 will get ContentMd5 from Object.
func (o *Object) GetContentMd5() (string, bool) {
	o.stat()

	if o.bit&objectIndexContentMd5 != 0 {
		return o.contentMd5, true
	}
	return "", false
}

// MustGetContentMd5 will get ContentMd5 from Object.
func (o *Object) MustGetContentMd5() string {
	o.stat()

	if o.bit&objectIndexContentMd5 == 0 {
		panic(fmt.Sprintf("object content_md5 is not set"))
	}
	return o.contentMd5
}

// SetContentMd5 will get ContentMd5 into Object.
func (o *Object) SetContentMd5(v string) *Object {
	o.contentMd5 = v
	o.bit |= objectIndexContentMd5
	return o
}

// GetContentType will get ContentType from Object.
func (o *Object) GetContentType() (string, bool) {
	o.stat()

	if o.bit&objectIndexContentType != 0 {
		return o.contentType, true
	}
	return "", false
}

// MustGetContentType will get ContentType from Object.
func (o *Object) MustGetContentType() string {
	o.stat()

	if o.bit&objectIndexContentType == 0 {
		panic(fmt.Sprintf("object content_type is not set"))
	}
	return o.contentType
}

// SetContentType will get ContentType into Object.
func (o *Object) SetContentType(v string) *Object {
	o.contentType = v
	o.bit |= objectIndexContentType
	return o
}

// GetEtag will get Etag from Object.
func (o *Object) GetEtag() (string, bool) {
	o.stat()

	if o.bit&objectIndexEtag != 0 {
		return o.etag, true
	}
	return "", false
}

// MustGetEtag will get Etag from Object.
func (o *Object) MustGetEtag() string {
	o.stat()

	if o.bit&objectIndexEtag == 0 {
		panic(fmt.Sprintf("object etag is not set"))
	}
	return o.etag
}

// SetEtag will get Etag into Object.
func (o *Object) SetEtag(v string) *Object {
	o.etag = v
	o.bit |= objectIndexEtag
	return o
}
func (o *Object) GetID() string {
	return o.ID
}
func (o *Object) SetID(v string) *Object {
	o.ID = v
	return o
}

// GetLastModified will get LastModified from Object.
func (o *Object) GetLastModified() (time.Time, bool) {
	o.stat()

	if o.bit&objectIndexLastModified != 0 {
		return o.lastModified, true
	}
	return time.Time{}, false
}

// MustGetLastModified will get LastModified from Object.
func (o *Object) MustGetLastModified() time.Time {
	o.stat()

	if o.bit&objectIndexLastModified == 0 {
		panic(fmt.Sprintf("object last_modified is not set"))
	}
	return o.lastModified
}

// SetLastModified will get LastModified into Object.
func (o *Object) SetLastModified(v time.Time) *Object {
	o.lastModified = v
	o.bit |= objectIndexLastModified
	return o
}

// GetLinkTarget will get LinkTarget from Object.
//
// LinkTarget is the symlink target for link object.
func (o *Object) GetLinkTarget() (string, bool) {
	o.stat()

	if o.bit&objectIndexLinkTarget != 0 {
		return o.linkTarget, true
	}
	return "", false
}

// MustGetLinkTarget will get LinkTarget from Object.
//
// LinkTarget is the symlink target for link object.
func (o *Object) MustGetLinkTarget() string {
	o.stat()

	if o.bit&objectIndexLinkTarget == 0 {
		panic(fmt.Sprintf("object link_target is not set"))
	}
	return o.linkTarget
}

// SetLinkTarget will get LinkTarget into Object.
//
// LinkTarget is the symlink target for link object.
func (o *Object) SetLinkTarget(v string) *Object {
	o.linkTarget = v
	o.bit |= objectIndexLinkTarget
	return o
}
func (o *Object) GetMode() ObjectMode {
	return o.Mode
}
func (o *Object) SetMode(v ObjectMode) *Object {
	o.Mode = v
	return o
}

// GetMultipartID will get MultipartID from Object.
//
// MultipartID is the part id of part object.
func (o *Object) GetMultipartID() (string, bool) {
	o.stat()

	if o.bit&objectIndexMultipartID != 0 {
		return o.multipartID, true
	}
	return "", false
}

// MustGetMultipartID will get MultipartID from Object.
//
// MultipartID is the part id of part object.
func (o *Object) MustGetMultipartID() string {
	o.stat()

	if o.bit&objectIndexMultipartID == 0 {
		panic(fmt.Sprintf("object multipart_id is not set"))
	}
	return o.multipartID
}

// SetMultipartID will get MultipartID into Object.
//
// MultipartID is the part id of part object.
func (o *Object) SetMultipartID(v string) *Object {
	o.multipartID = v
	o.bit |= objectIndexMultipartID
	return o
}
func (o *Object) GetPath() string {
	return o.Path
}
func (o *Object) SetPath(v string) *Object {
	o.Path = v
	return o
}

// GetSystemMetadata will get SystemMetadata from Object.
//
// SystemMetadata stores system defined metadata.
func (o *Object) GetSystemMetadata() (interface{}, bool) {
	o.stat()

	if o.bit&objectIndexSystemMetadata != 0 {
		return o.systemMetadata, true
	}
	return nil, false
}

// MustGetSystemMetadata will get SystemMetadata from Object.
//
// SystemMetadata stores system defined metadata.
func (o *Object) MustGetSystemMetadata() interface{} {
	o.stat()

	if o.bit&objectIndexSystemMetadata == 0 {
		panic(fmt.Sprintf("object system_metadata is not set"))
	}
	return o.systemMetadata
}

// SetSystemMetadata will get SystemMetadata into Object.
//
// SystemMetadata stores system defined metadata.
func (o *Object) SetSystemMetadata(v interface{}) *Object {
	o.systemMetadata = v
	o.bit |= objectIndexSystemMetadata
	return o
}

// GetUserMetadata will get UserMetadata from Object.
//
// UserMetadata stores user defined metadata.
func (o *Object) GetUserMetadata() (map[string]string, bool) {
	o.stat()

	if o.bit&objectIndexUserMetadata != 0 {
		return o.userMetadata, true
	}
	return map[string]string{}, false
}

// MustGetUserMetadata will get UserMetadata from Object.
//
// UserMetadata stores user defined metadata.
func (o *Object) MustGetUserMetadata() map[string]string {
	o.stat()

	if o.bit&objectIndexUserMetadata == 0 {
		panic(fmt.Sprintf("object user_metadata is not set"))
	}
	return o.userMetadata
}

// SetUserMetadata will get UserMetadata into Object.
//
// UserMetadata stores user defined metadata.
func (o *Object) SetUserMetadata(v map[string]string) *Object {
	o.userMetadata = v
	o.bit |= objectIndexUserMetadata
	return o
}
func (o *Object) clone(xo *Object) {
	o.appendOffset = xo.appendOffset
	o.contentDisposition = xo.contentDisposition
	o.contentLength = xo.contentLength
	o.contentMd5 = xo.contentMd5
	o.contentType = xo.contentType
	o.etag = xo.etag
	o.ID = xo.ID
	o.lastModified = xo.lastModified
	o.linkTarget = xo.linkTarget
	o.Mode = xo.Mode
	o.multipartID = xo.multipartID
	o.Path = xo.Path
	o.systemMetadata = xo.systemMetadata
	o.userMetadata = xo.userMetadata
	o.bit = xo.bit
}
