package histutil

import (
	

	
)

// DB is the interface of the storage database.
type DB interface {
	NextCmdSeq() (int, error)
	AddCmd(cmd string) (int, error)
	CmdsWithSeq(from, upto int) ([]store.Cmd, error)
	PrevCmd(upto int, prefix string) (store.Cmd, error)
	NextCmd(from int, prefix string) (store.Cmd, error)
}

// FaultyInMemoryDB is an in-memory DB implementation that can be injected
// one-off errors. It is useful in tests.
type FaultyInMemoryDB interface {
	DB
	// SetOneOffError causes the next operation on the database to return the
	// given error.
	SetOneOffError(err error)
}

// NewFaultyInMemoryDB creates a new FaultyInMemoryDB with the given commands.
func ( ...string) FaultyInMemoryDB {
	return &testDB{cmds: }
}

// Implementation of FaultyInMemoryDB.
type testDB struct {
	cmds        []string
	oneOffError error
}

func ( *testDB) ( error) {
	.oneOffError = 
}

func ( *testDB) () error {
	 := .oneOffError
	.oneOffError = nil
	return 
}

func ( *testDB) () (int, error) {
	return len(.cmds), .error()
}

func ( *testDB) ( string) (int, error) {
	if .oneOffError != nil {
		return -1, .error()
	}
	.cmds = append(.cmds, )
	return len(.cmds) - 1, nil
}

func ( *testDB) (,  int) ([]store.Cmd, error) {
	if  := .error();  != nil {
		return nil, 
	}
	if  < 0 {
		 = 0
	}
	if  < 0 ||  > len(.cmds) {
		 = len(.cmds)
	}
	var  []store.Cmd
	for  := ;  < ; ++ {
		 = append(, store.Cmd{Text: .cmds[], Seq: })
	}
	return , nil
}

func ( *testDB) ( int,  string) (store.Cmd, error) {
	if .oneOffError != nil {
		return store.Cmd{}, .error()
	}
	if  < 0 ||  > len(.cmds) {
		 = len(.cmds)
	}
	for  :=  - 1;  >= 0; -- {
		if strings.HasPrefix(.cmds[], ) {
			return store.Cmd{Text: .cmds[], Seq: }, nil
		}
	}
	return store.Cmd{}, store.ErrNoMatchingCmd
}

func ( *testDB) ( int,  string) (store.Cmd, error) {
	if .oneOffError != nil {
		return store.Cmd{}, .error()
	}
	if  < 0 {
		 = 0
	}
	for  := ;  < len(.cmds); ++ {
		if strings.HasPrefix(.cmds[], ) {
			return store.Cmd{Text: .cmds[], Seq: }, nil
		}
	}
	return store.Cmd{}, store.ErrNoMatchingCmd
}