package dns

import (
	"bytes"
	"fmt"
	"io"
	"strconv"
	"strings"
)

// Parse the $GENERATE statement as used in BIND9 zones.
// See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
// We are called after '$GENERATE '. After which we expect:
// * the range (12-24/2)
// * lhs (ownername)
// * [[ttl][class]]
// * type
// * rhs (rdata)
// But we are lazy here, only the range is parsed *all* occurrences
// of $ after that are interpreted.
func (zp *ZoneParser) generate(l lex) (RR, bool) {
	token := l.token
	step := 1
	if i := strings.IndexByte(token, '/'); i >= 0 {
		if i+1 == len(token) {
			return zp.setParseError("bad step in $GENERATE range", l)
		}

		s, err := strconv.Atoi(token[i+1:])
		if err != nil || s <= 0 {
			return zp.setParseError("bad step in $GENERATE range", l)
		}

		step = s
		token = token[:i]
	}

	sx := strings.SplitN(token, "-", 2)
	if len(sx) != 2 {
		return zp.setParseError("bad start-stop in $GENERATE range", l)
	}

	start, err := strconv.Atoi(sx[0])
	if err != nil {
		return zp.setParseError("bad start in $GENERATE range", l)
	}

	end, err := strconv.Atoi(sx[1])
	if err != nil {
		return zp.setParseError("bad stop in $GENERATE range", l)
	}
	if end < 0 || start < 0 || end < start || (end-start)/step > 65535 {
		return zp.setParseError("bad range in $GENERATE range", l)
	}

	// _BLANK
	l, ok := zp.c.Next()
	if !ok || l.value != zBlank {
		return zp.setParseError("garbage after $GENERATE range", l)
	}

	// Create a complete new string, which we then parse again.
	var s string
	for l, ok := zp.c.Next(); ok; l, ok = zp.c.Next() {
		if l.err {
			return zp.setParseError("bad data in $GENERATE directive", l)
		}
		if l.value == zNewline {
			break
		}

		s += l.token
	}

	r := &generateReader{
		s: s,

		cur:   start,
		start: start,
		end:   end,
		step:  step,

		file: zp.file,
		lex:  &l,
	}
	zp.sub = NewZoneParser(r, zp.origin, zp.file)
	zp.sub.includeDepth, zp.sub.includeAllowed = zp.includeDepth, zp.includeAllowed
	zp.sub.generateDisallowed = true
	zp.sub.SetDefaultTTL(defaultTtl)
	return zp.subNext()
}

type generateReader struct {
	s  string
	si int

	cur   int
	start int
	end   int
	step  int

	mod bytes.Buffer

	escape bool

	eof bool

	file string
	lex  *lex
}

func (r *generateReader) parseError(msg string, end int) *ParseError {
	r.eof = true // Make errors sticky.

	l := *r.lex
	l.token = r.s[r.si-1 : end]
	l.column += r.si // l.column starts one zBLANK before r.s

	return &ParseError{r.file, msg, l}
}

func (r *generateReader) Read(p []byte) (int, error) {
	// NewZLexer, through NewZoneParser, should use ReadByte and
	// not end up here.

	panic("not implemented")
}

func (r *generateReader) ReadByte() (byte, error) {
	if r.eof {
		return 0, io.EOF
	}
	if r.mod.Len() > 0 {
		return r.mod.ReadByte()
	}

	if r.si >= len(r.s) {
		r.si = 0
		r.cur += r.step

		r.eof = r.cur > r.end || r.cur < 0
		return '\n', nil
	}

	si := r.si
	r.si++

	switch r.s[si] {
	case '\\':
		if r.escape {
			r.escape = false
			return '\\', nil
		}

		r.escape = true
		return r.ReadByte()
	case '$':
		if r.escape {
			r.escape = false
			return '$', nil
		}

		mod := "%d"

		if si >= len(r.s)-1 {
			// End of the string
			fmt.Fprintf(&r.mod, mod, r.cur)
			return r.mod.ReadByte()
		}

		if r.s[si+1] == '$' {
			r.si++
			return '$', nil
		}

		var offset int

		// Search for { and }
		if r.s[si+1] == '{' {
			// Modifier block
			sep := strings.Index(r.s[si+2:], "}")
			if sep < 0 {
				return 0, r.parseError("bad modifier in $GENERATE", len(r.s))
			}

			var errMsg string
			mod, offset, errMsg = modToPrintf(r.s[si+2 : si+2+sep])
			if errMsg != "" {
				return 0, r.parseError(errMsg, si+3+sep)
			}
			if r.start+offset < 0 || r.end+offset > 1<<31-1 {
				return 0, r.parseError("bad offset in $GENERATE", si+3+sep)
			}

			r.si += 2 + sep // Jump to it
		}

		fmt.Fprintf(&r.mod, mod, r.cur+offset)
		return r.mod.ReadByte()
	default:
		if r.escape { // Pretty useless here
			r.escape = false
			return r.ReadByte()
		}

		return r.s[si], nil
	}
}

// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
func modToPrintf(s string) (string, int, string) {
	// Modifier is { offset [ ,width [ ,base ] ] } - provide default
	// values for optional width and type, if necessary.
	var offStr, widthStr, base string
	switch xs := strings.Split(s, ","); len(xs) {
	case 1:
		offStr, widthStr, base = xs[0], "0", "d"
	case 2:
		offStr, widthStr, base = xs[0], xs[1], "d"
	case 3:
		offStr, widthStr, base = xs[0], xs[1], xs[2]
	default:
		return "", 0, "bad modifier in $GENERATE"
	}

	switch base {
	case "o", "d", "x", "X":
	default:
		return "", 0, "bad base in $GENERATE"
	}

	offset, err := strconv.Atoi(offStr)
	if err != nil {
		return "", 0, "bad offset in $GENERATE"
	}

	width, err := strconv.Atoi(widthStr)
	if err != nil || width < 0 || width > 255 {
		return "", 0, "bad width in $GENERATE"
	}

	if width == 0 {
		return "%" + base, offset, ""
	}

	return "%0" + widthStr + base, offset, ""
}
