// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package width

import (
	"unicode/utf8"

	"golang.org/x/text/transform"
)

type foldTransform struct {
	transform.NopResetter
}

func (foldTransform) Span(src []byte, atEOF bool) (n int, err error) {
	for n < len(src) {
		if src[n] < utf8.RuneSelf {
			// ASCII fast path.
			for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
			}
			continue
		}
		v, size := trie.lookup(src[n:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				err = transform.ErrShortSrc
			} else {
				n = len(src)
			}
			break
		}
		if elem(v)&tagNeedsFold != 0 {
			err = transform.ErrEndOfSpan
			break
		}
		n += size
	}
	return n, err
}

func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	for nSrc < len(src) {
		if src[nSrc] < utf8.RuneSelf {
			// ASCII fast path.
			start, end := nSrc, len(src)
			if d := len(dst) - nDst; d < end-start {
				end = nSrc + d
			}
			for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
			}
			n := copy(dst[nDst:], src[start:nSrc])
			if nDst += n; nDst == len(dst) {
				nSrc = start + n
				if nSrc == len(src) {
					return nDst, nSrc, nil
				}
				if src[nSrc] < utf8.RuneSelf {
					return nDst, nSrc, transform.ErrShortDst
				}
			}
			continue
		}
		v, size := trie.lookup(src[nSrc:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				return nDst, nSrc, transform.ErrShortSrc
			}
			size = 1 // gobble 1 byte
		}
		if elem(v)&tagNeedsFold == 0 {
			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			nDst += size
		} else {
			data := inverseData[byte(v)]
			if len(dst)-nDst < int(data[0]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			i := 1
			for end := int(data[0]); i < end; i++ {
				dst[nDst] = data[i]
				nDst++
			}
			dst[nDst] = data[i] ^ src[nSrc+size-1]
			nDst++
		}
		nSrc += size
	}
	return nDst, nSrc, nil
}

type narrowTransform struct {
	transform.NopResetter
}

func (narrowTransform) Span(src []byte, atEOF bool) (n int, err error) {
	for n < len(src) {
		if src[n] < utf8.RuneSelf {
			// ASCII fast path.
			for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
			}
			continue
		}
		v, size := trie.lookup(src[n:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				err = transform.ErrShortSrc
			} else {
				n = len(src)
			}
			break
		}
		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
		} else {
			err = transform.ErrEndOfSpan
			break
		}
		n += size
	}
	return n, err
}

func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	for nSrc < len(src) {
		if src[nSrc] < utf8.RuneSelf {
			// ASCII fast path.
			start, end := nSrc, len(src)
			if d := len(dst) - nDst; d < end-start {
				end = nSrc + d
			}
			for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
			}
			n := copy(dst[nDst:], src[start:nSrc])
			if nDst += n; nDst == len(dst) {
				nSrc = start + n
				if nSrc == len(src) {
					return nDst, nSrc, nil
				}
				if src[nSrc] < utf8.RuneSelf {
					return nDst, nSrc, transform.ErrShortDst
				}
			}
			continue
		}
		v, size := trie.lookup(src[nSrc:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				return nDst, nSrc, transform.ErrShortSrc
			}
			size = 1 // gobble 1 byte
		}
		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			nDst += size
		} else {
			data := inverseData[byte(v)]
			if len(dst)-nDst < int(data[0]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			i := 1
			for end := int(data[0]); i < end; i++ {
				dst[nDst] = data[i]
				nDst++
			}
			dst[nDst] = data[i] ^ src[nSrc+size-1]
			nDst++
		}
		nSrc += size
	}
	return nDst, nSrc, nil
}

type wideTransform struct {
	transform.NopResetter
}

func (wideTransform) Span(src []byte, atEOF bool) (n int, err error) {
	for n < len(src) {
		// TODO: Consider ASCII fast path. Special-casing ASCII handling can
		// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
		// not enough to warrant the extra code and complexity.
		v, size := trie.lookup(src[n:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				err = transform.ErrShortSrc
			} else {
				n = len(src)
			}
			break
		}
		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
		} else {
			err = transform.ErrEndOfSpan
			break
		}
		n += size
	}
	return n, err
}

func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	for nSrc < len(src) {
		// TODO: Consider ASCII fast path. Special-casing ASCII handling can
		// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
		// not enough to warrant the extra code and complexity.
		v, size := trie.lookup(src[nSrc:])
		if size == 0 { // incomplete UTF-8 encoding
			if !atEOF {
				return nDst, nSrc, transform.ErrShortSrc
			}
			size = 1 // gobble 1 byte
		}
		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			nDst += size
		} else {
			data := inverseData[byte(v)]
			if len(dst)-nDst < int(data[0]) {
				return nDst, nSrc, transform.ErrShortDst
			}
			i := 1
			for end := int(data[0]); i < end; i++ {
				dst[nDst] = data[i]
				nDst++
			}
			dst[nDst] = data[i] ^ src[nSrc+size-1]
			nDst++
		}
		nSrc += size
	}
	return nDst, nSrc, nil
}
