package vfs

import (
	
	
	
	
	
	
	
)

type vfsOS struct{}

func (vfsOS) ( string) (string, error) {
	,  := evalSymlinks()
	if  != nil {
		return "", 
	}
	,  := filepath.Abs()
	if  == nil &&  !=  {
		 = _OK_SYMLINK
	}
	return , 
}

func evalSymlinks( string) (string, error) {
	var  string
	,  := os.Lstat()
	if errors.Is(, fs.ErrNotExist) {
		,  = filepath.Split()
	}
	,  = filepath.EvalSymlinks()
	if  != nil {
		return "", 
	}
	return filepath.Join(, ), nil
}

func (vfsOS) ( string,  bool) error {
	 := os.Remove()
	if errors.Is(, fs.ErrNotExist) {
		return _IOERR_DELETE_NOENT
	}
	if  != nil {
		return 
	}
	if isUnix &&  {
		,  := os.Open(filepath.Dir())
		if  != nil {
			return _OK
		}
		defer .Close()
		 = osSync(, 0, SYNC_FULL)
		if  != nil {
			return _IOERR_DIR_FSYNC
		}
	}
	return nil
}

func (vfsOS) ( string,  AccessFlag) (bool, error) {
	 := osAccess(, )
	if  == ACCESS_EXISTS {
		if errors.Is(, fs.ErrNotExist) {
			return false, nil
		}
	} else {
		if errors.Is(, fs.ErrPermission) {
			return false, nil
		}
	}
	return  == nil, 
}

func (vfsOS) ( string,  OpenFlag) (File, OpenFlag, error) {
	// notest // OpenFilename is called instead
	if  == "" {
		return vfsOS{}.OpenFilename(nil, )
	}
	return nil, 0, _CANTOPEN
}

func (vfsOS) ( *Filename,  OpenFlag) (File, OpenFlag, error) {
	 := _O_NOFOLLOW
	if &OPEN_EXCLUSIVE != 0 {
		 |= os.O_EXCL
	}
	if &OPEN_CREATE != 0 {
		 |= os.O_CREATE
	}
	if &OPEN_READONLY != 0 {
		 |= os.O_RDONLY
	}
	if &OPEN_READWRITE != 0 {
		 |= os.O_RDWR
	}

	 := &(OPEN_CREATE) != 0
	 := &(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0

	var  error
	var  *os.File
	if  == nil {
		,  = os.CreateTemp(os.Getenv("SQLITE_TMPDIR"), "*.db")
	} else {
		,  = os.OpenFile(.String(), , 0666)
	}
	if  != nil {
		if  == nil {
			return nil, , _IOERR_GETTEMPPATH
		}
		if errors.Is(, syscall.EISDIR) {
			return nil, , _CANTOPEN_ISDIR
		}
		if  &&  && errors.Is(, fs.ErrPermission) &&
			osAccess(.String(), ACCESS_EXISTS) != nil {
			return nil, , _READONLY_DIRECTORY
		}
		return nil, , 
	}

	if  := .URIParameter("modeof");  != "" {
		if  = osSetMode(, );  != nil {
			.Close()
			return nil, , _IOERR_FSTAT
		}
	}
	if isUnix && &OPEN_DELETEONCLOSE != 0 {
		os.Remove(.Name())
	}

	 := vfsFile{
		File:  ,
		flags:  | _FLAG_PSOW,
		shm:   NewSharedMemory(.String()+"-shm", ),
	}
	if osBatchAtomic() {
		.flags |= _FLAG_ATOMIC
	}
	if isUnix &&  &&  {
		.flags |= _FLAG_SYNC_DIR
	}
	return &, , nil
}

type vfsFile struct {
	*os.File
	shm   SharedMemory
	lock  LockLevel
	flags OpenFlag
}

var (
	// Ensure these interfaces are implemented:
	_ FileLockState          = &vfsFile{}
	_ FileHasMoved           = &vfsFile{}
	_ FileSizeHint           = &vfsFile{}
	_ FilePersistWAL         = &vfsFile{}
	_ FilePowersafeOverwrite = &vfsFile{}
)

func ( *vfsFile) () error {
	if !isUnix && .flags&OPEN_DELETEONCLOSE != 0 {
		defer os.Remove(.Name())
	}
	if .shm != nil {
		.shm.Close()
	}
	.Unlock(LOCK_NONE)
	return .File.Close()
}

func ( *vfsFile) ( []byte,  int64) ( int,  error) {
	return osReadAt(.File, , )
}

func ( *vfsFile) ( []byte,  int64) ( int,  error) {
	return osWriteAt(.File, , )
}

func ( *vfsFile) ( SyncFlag) error {
	 := osSync(.File, .flags, )
	if  != nil {
		return 
	}
	if isUnix && .flags&_FLAG_SYNC_DIR != 0 {
		.flags ^= _FLAG_SYNC_DIR
		,  := os.Open(filepath.Dir(.File.Name()))
		if  != nil {
			return nil
		}
		defer .Close()
		 = osSync(.File, .flags, )
		if  != nil {
			return _IOERR_DIR_FSYNC
		}
	}
	return nil
}

func ( *vfsFile) () (int64, error) {
	return .Seek(0, io.SeekEnd)
}

func ( *vfsFile) () int {
	return _DEFAULT_SECTOR_SIZE
}

func ( *vfsFile) () DeviceCharacteristic {
	 := IOCAP_SUBPAGE_READ
	if .flags&_FLAG_ATOMIC != 0 {
		 |= IOCAP_BATCH_ATOMIC
	}
	if .flags&_FLAG_PSOW != 0 {
		 |= IOCAP_POWERSAFE_OVERWRITE
	}
	if runtime.GOOS == "windows" {
		 |= IOCAP_UNDELETABLE_WHEN_OPEN
	}
	return 
}

func ( *vfsFile) ( int64) error {
	return osAllocate(.File, )
}

func ( *vfsFile) () (bool, error) {
	if runtime.GOOS == "windows" {
		return false, nil
	}
	,  := .Stat()
	if  != nil {
		return false, 
	}
	,  := os.Stat(.Name())
	if errors.Is(, fs.ErrNotExist) {
		return true, nil
	}
	if  != nil {
		return false, 
	}
	return !os.SameFile(, ), nil
}

func ( *vfsFile) () LockLevel     { return .lock }
func ( *vfsFile) () bool { return .flags&_FLAG_PSOW != 0 }
func ( *vfsFile) () bool         { return .flags&_FLAG_KEEP_WAL != 0 }

func ( *vfsFile) ( bool) {
	.flags &^= _FLAG_PSOW
	if  {
		.flags |= _FLAG_PSOW
	}
}

func ( *vfsFile) ( bool) {
	.flags &^= _FLAG_KEEP_WAL
	if  {
		.flags |= _FLAG_KEEP_WAL
	}
}