// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package storage provides storage abstraction for LevelDB.
package storage

import (
	"errors"
	"fmt"
	"io"

	"github.com/syndtr/goleveldb/leveldb/util"
)

type FileType uint32

const (
	TypeManifest FileType = 1 << iota
	TypeJournal
	TypeTable
	TypeTemp

	TypeAll = TypeManifest | TypeJournal | TypeTable | TypeTemp
)

func (t FileType) String() string {
	switch t {
	case TypeManifest:
		return "manifest"
	case TypeJournal:
		return "journal"
	case TypeTable:
		return "table"
	case TypeTemp:
		return "temp"
	}
	return fmt.Sprintf("<unknown:%d>", t)
}

var (
	ErrInvalidFile = errors.New("leveldb/storage: invalid file for argument")
	ErrLocked      = errors.New("leveldb/storage: already locked")
	ErrClosed      = errors.New("leveldb/storage: closed")
)

// ErrCorrupted is the type that wraps errors that indicate corruption of
// a file. Package storage has its own type instead of using
// errors.ErrCorrupted to prevent circular import.
type ErrCorrupted struct {
	File *FileInfo
	Err  error
}

func (e *ErrCorrupted) Error() string {
	if e.File != nil {
		return fmt.Sprintf("%v [file=%v]", e.Err, e.File)
	} else {
		return e.Err.Error()
	}
}

// Syncer is the interface that wraps basic Sync method.
type Syncer interface {
	// Sync commits the current contents of the file to stable storage.
	Sync() error
}

// Reader is the interface that groups the basic Read, Seek, ReadAt and Close
// methods.
type Reader interface {
	io.ReadSeeker
	io.ReaderAt
	io.Closer
}

// Writer is the interface that groups the basic Write, Sync and Close
// methods.
type Writer interface {
	io.WriteCloser
	Syncer
}

// File is the file. A file instance must be goroutine-safe.
type File interface {
	// Open opens the file for read. Returns os.ErrNotExist error
	// if the file does not exist.
	// Returns ErrClosed if the underlying storage is closed.
	Open() (r Reader, err error)

	// Create creates the file for writting. Truncate the file if
	// already exist.
	// Returns ErrClosed if the underlying storage is closed.
	Create() (w Writer, err error)

	// Replace replaces file with newfile.
	// Returns ErrClosed if the underlying storage is closed.
	Replace(newfile File) error

	// Type returns the file type
	Type() FileType

	// Num returns the file number.
	Num() uint64

	// Remove removes the file.
	// Returns ErrClosed if the underlying storage is closed.
	Remove() error
}

// Storage is the storage. A storage instance must be goroutine-safe.
type Storage interface {
	// Lock locks the storage. Any subsequent attempt to call Lock will fail
	// until the last lock released.
	// After use the caller should call the Release method.
	Lock() (l util.Releaser, err error)

	// Log logs a string. This is used for logging. An implementation
	// may write to a file, stdout or simply do nothing.
	Log(str string)

	// GetFile returns a file for the given number and type. GetFile will never
	// returns nil, even if the underlying storage is closed.
	GetFile(num uint64, t FileType) File

	// GetFiles returns a slice of files that match the given file types.
	// The file types may be OR'ed together.
	GetFiles(t FileType) ([]File, error)

	// GetManifest returns a manifest file. Returns os.ErrNotExist if manifest
	// file does not exist.
	GetManifest() (File, error)

	// SetManifest sets the given file as manifest file. The given file should
	// be a manifest file type or error will be returned.
	SetManifest(f File) error

	// Close closes the storage. It is valid to call Close multiple times.
	// Other methods should not be called after the storage has been closed.
	Close() error
}

// FileInfo wraps basic file info.
type FileInfo struct {
	Type FileType
	Num  uint64
}

func (fi FileInfo) String() string {
	switch fi.Type {
	case TypeManifest:
		return fmt.Sprintf("MANIFEST-%06d", fi.Num)
	case TypeJournal:
		return fmt.Sprintf("%06d.log", fi.Num)
	case TypeTable:
		return fmt.Sprintf("%06d.ldb", fi.Num)
	case TypeTemp:
		return fmt.Sprintf("%06d.tmp", fi.Num)
	default:
		return fmt.Sprintf("%#x-%d", fi.Type, fi.Num)
	}
}

// NewFileInfo creates new FileInfo from the given File. It will returns nil
// if File is nil.
func NewFileInfo(f File) *FileInfo {
	if f == nil {
		return nil
	}
	return &FileInfo{f.Type(), f.Num()}
}
