package nori

import (
	"bufio"
	"io"
)

func discardN(r io.Reader, count int) error {
	if rd, ok := r.(*bufio.Reader); ok {
		if _, err := rd.Discard(count); err != nil {
			return err
		}
	} else if rd, ok := r.(readByteSeeker); ok {
		_, err := rd.Seek(int64(count), io.SeekCurrent)
		if err != nil {
			return err
		}
	} else if _, err := io.CopyN(io.Discard, r, int64(count)); err != nil {
		return err
	}
	return nil
}

func readByte(r io.Reader) (byte, error) {
	if rd, ok := r.(readByteSeeker); ok {
		return rd.ReadByte()
	} else {
		b := [1]byte{}
		_, err := io.ReadFull(r, b[:])
		if err != nil {
			return 0, err
		}
		return b[0], nil
	}
}

type readByteSeeker interface {
	io.Reader
	io.Seeker
	io.ByteReader
}

func reflectReader(r io.Reader) io.Reader {
	if _, ok := r.(readByteSeeker); ok {
		return r
	}
	return fileByteReader{
		ReadSeeker: r.(io.ReadSeeker),
	}
}

type fileByteReader struct {
	io.ReadSeeker
}

func (o *fileByteReader) ReadByte() (byte, error) {
	b := [1]byte{}
	_, err := o.Read(b[:])
	return b[0], err
}
