// Copyright 2018 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

package main

// print-crc32-example.go prints the worked examples from std/crc32/README.md.
//
// Usage: go run print-crc32-example.go

import (
	"bytes"
	"os"
)

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	do(false, 4, 0xC, makeBinaryData("H"))
	os.Stdout.WriteString("\n")
	do(true, 32, 0xEDB88320, makeBinaryData("Hi\n"))
	return nil
}

func bit(b bool) byte {
	if b {
		return '1'
	}
	return '0'
}

func hex(b []byte) byte {
	x := byte(0)
	x |= (b[0] - '0') << 0
	x |= (b[1] - '0') << 1
	x |= (b[2] - '0') << 2
	x |= (b[3] - '0') << 3
	if x < 10 {
		return '0' + x
	}
	return 'A' + (x - 10)
}

func makeBinaryData(data string) []byte {
	b := make([]byte, len(data)*8)
	for i := range b {
		mask := uint8(1) << uint(i&7)
		b[i] = bit(data[i>>3]&mask != 0)
	}
	return b
}

func makePoly(n int, bits uint64) []byte {
	b := make([]byte, n+1)
	b[0] = '1'
	for i := 0; i < n; i++ {
		mask := uint64(1) << uint(i)
		b[i+1] = bit(bits&mask != 0)
	}
	return b
}

func show(prefix string, indent int, binaryData []byte) {
	const nineSpaces = "         "
	os.Stdout.WriteString(prefix)
	for ; indent >= 8; indent -= 8 {
		os.Stdout.WriteString(nineSpaces)
	}
	os.Stdout.WriteString(nineSpaces[:indent])
	for {
		b, remaining := binaryData, []byte(nil)
		if len(b) > 8-indent {
			b, remaining = b[:8-indent], b[8-indent:]
			indent = 0
		}
		os.Stdout.WriteString(string(b))
		if len(remaining) == 0 {
			break
		}
		os.Stdout.WriteString(" ")
		binaryData = remaining
	}
	os.Stdout.WriteString("\n")
}

func do(invert bool, polyN int, polyBits uint64, binaryData []byte) {
	poly := makePoly(polyN, polyBits)

	indent := 0
	n := len(binaryData)
	show("input   ", 0, binaryData)
	binaryData = append(binaryData, bytes.Repeat([]byte("0"), polyN)...)
	show("pad     ", 0, binaryData)

	if invert {
		for i := 0; i < polyN; i++ {
			binaryData[i] ^= 1
		}
		show("invert  ", 0, binaryData)
	}

	for {
		indent = bytes.IndexByte(binaryData[:n], '1')
		if indent < 0 {
			break
		}
		show("divisor ", indent, poly)
		for i := range poly {
			binaryData[indent+i] = bit(binaryData[indent+i] != poly[i])
		}
		show("xor     ", 0, binaryData)
	}

	for i := 0; i < n; i++ {
		binaryData[i] = ' '
	}
	show("remain  ", 0, binaryData)

	if invert {
		for i := 0; i < polyN; i++ {
			binaryData[n+i] ^= 1
		}
		show("invert  ", 0, binaryData)

		if polyN&3 == 0 {
			for i := 0; i < polyN; i += 4 {
				h := hex(binaryData[n+i : n+i+4])
				binaryData[n+i+0] = ' '
				binaryData[n+i+1] = ' '
				binaryData[n+i+2] = ' '
				binaryData[n+i+3] = h
			}
			show("hex     ", 0, binaryData)
		}
	}
}
