// Copyright 2020 The Fuchsia 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 main

import (
	"encoding/hex"
	"errors"
	"fmt"
	"strconv"
	"strings"
	"text/scanner"
	"unicode"
)

func parseBytes(input string) ([]byte, scanner.Position, error) {
	var s scanner.Scanner
	s.Init(strings.NewReader(input))
	s.Filename = "fidlbolt.bytes"
	s.Mode = scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments

	var err error
	s.Error = func(s *scanner.Scanner, msg string) {
		err = errors.New(msg)
	}

	var result []byte
	var token strings.Builder
	listMode := false
	firstOfLine := true
	for tok := s.Scan(); tok != scanner.EOF && err == nil; tok = s.Scan() {
		endToken := false
		thisListMode := listMode
		thisFirstOfLine := firstOfLine
		switch tok {
		case scanner.String:
			var str string
			str, err = strconv.Unquote(s.TokenText())
			if err != nil {
				break
			}
			result = append(result, []byte(str)...)
		case ',':
			endToken = true
		case '[':
			endToken = true
			if listMode {
				err = errors.New(`unexpected "[" inside list`)
			}
			listMode = true
		case ']':
			endToken = true
			if !listMode {
				err = errors.New(`unexpected character "]"`)
			}
			listMode = false
		default:
			token.WriteRune(tok)
			switch s.Peek() {
			case '\n', '\r':
				firstOfLine = true
				fallthrough
			case '\t', ' ', scanner.EOF:
				endToken = true
			}
		}
		if err != nil {
			break
		}
		if endToken && token.Len() > 0 {
			str := token.String()
			if thisFirstOfLine && str[len(str)-1] == ':' {
				token.Reset()
				continue
			}
			var b []byte
			if thisListMode {
				b, err = parseSingleByteToken(str)
			} else {
				b, err = parseToken(str)
			}
			if err != nil {
				break
			}
			token.Reset()
			result = append(result, b...)
		}
	}
	if err != nil {
		return nil, s.Position, err
	}
	return result, s.Position, nil
}

func parseSingleByteToken(text string) ([]byte, error) {
	num, err := strconv.ParseUint(text, 0, 64)
	if err != nil {
		return nil, err
	}
	if num < 0 || num > 255 {
		return nil, fmt.Errorf("byte %s out of range (must be 0-255)", text)
	}
	return []byte{byte(num)}, nil
}

func parseToken(text string) ([]byte, error) {
	negative := false
	if strings.HasPrefix(text, "-") {
		negative = true
		text = text[1:]
	}
	var suffix string
	i := strings.LastIndexAny(text, "ui")
	if i != -1 {
		suffix = text[i:]
		text = text[:i]
	}
	if suffix == "" {
		if negative {
			return nil, fmt.Errorf("invalid use of negation")
		}
		if strings.HasPrefix(text, "0x") {
			text = text[2:]
		}
		if len(text)%2 != 0 {
			return nil, fmt.Errorf("hex must have an even number of characters")
		}
		for _, c := range text {
			if !(('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) {
				return nil, fmt.Errorf("invalid character %q", string(c))
			}
		}
		return hex.DecodeString(text)
	}
	num, err := strconv.ParseUint(text, 0, 64)
	if err != nil {
		return nil, err
	}
	var signed bool
	switch suffix[0] {
	case 'u':
		signed = false
		if negative {
			return nil, fmt.Errorf("cannot have negative unsigned number")
		}
	case 'i':
		signed = true
	default:
		return nil, fmt.Errorf("invalid number suffix %q", suffix)
	}
	bits, err := strconv.ParseUint(suffix[1:], 10, 64)
	if err != nil {
		return nil, err
	}
	if bits != 8 && bits != 16 && bits != 32 && bits != 64 {
		return nil, fmt.Errorf("invalid bit width %d", bits)
	}
	max := uint64(1) << bits
	if signed {
		max = uint64(1) << (bits - 1)
		if !negative {
			max--
		}
	}
	if num >= max && max != 0 {
		return nil, fmt.Errorf("%s out of range for %s", text, suffix)
	}
	if negative {
		// Num is uint64, so this will wrap around, storing the two's
		// complement. We do this instead of just parsing the full text
		// (possibly with "-") as int64 because with int64 we would not
		// be able to store the largest u64 values.
		num = -num
	}
	switch bits {
	case 8:
		return []byte{byte(num)}, nil
	case 16:
		return []byte{byte(num & 0xff), byte(num >> 8 & 0xff)}, nil
	case 32:
		return []byte{
			byte(num & 0xff), byte(num >> 8 & 0xff), byte(num >> 16 & 0xff), byte(num >> 24 & 0xff),
		}, nil
	case 64:
		return []byte{
			byte(num & 0xff), byte(num >> 8 & 0xff), byte(num >> 16 & 0xff), byte(num >> 24 & 0xff),
			byte(num >> 32 & 0xff), byte(num >> 40 & 0xff), byte(num >> 48 & 0xff), byte(num >> 56 & 0xff),
		}, nil
	}
	return nil, fmt.Errorf("non-exhaustive")
}

func formatBytes(bytes []byte, options *Options) (string, error) {
	byteFmt, offsetFmt := "%02x", "%08x: "
	if options.Capital {
		byteFmt, offsetFmt = "%02X", "%08X: "
	}
	group := options.Group
	if group < 1 {
		group = 1
	}
	if group > options.Columns {
		group = options.Columns
	}
	for options.Columns%group != 0 {
		group--
	}

	var builder strings.Builder
	writeASCII := func(start, end int) {
		builder.WriteString("  // ")
		for i := start; i < end; i++ {
			r := rune(bytes[i])
			if r <= unicode.MaxASCII && unicode.IsPrint(r) {
				builder.WriteRune(r)
			} else {
				builder.WriteByte('.')
			}
		}
	}

	for i, b := range bytes {
		if i%options.Columns == 0 {
			if i != 0 {
				if options.ASCII {
					writeASCII(i-options.Columns, i)
				}
				builder.WriteByte('\n')
			}
			if options.Offsets {
				builder.WriteString(fmt.Sprintf(offsetFmt, i))
			}
		} else if i%group == 0 {
			builder.WriteByte(' ')
		}
		builder.WriteString(fmt.Sprintf(byteFmt, b))
	}
	if options.ASCII {
		last := len(bytes) % options.Columns
		left := options.Columns - last
		if last == 0 {
			left = 0
		}
		spaces := left/group*(group*2+1) + left%group*2
		for i := 0; i < spaces; i++ {
			builder.WriteByte(' ')
		}
		writeASCII(len(bytes)-last, len(bytes))
	}
	return builder.String(), nil
}
