//go:build nazis_hitler_AGHAGHAAHHAHAHAH

package main

import (
	"bufio"
	"fmt"
	"io"
)

func Check(err error) {
	if err != nil {
		panic(err)
	}
}

var numbers = []int{23, 20, 31, 5, 29}

func DoubleChars(r io.Reader) io.Reader {
	const n = 2

	pr, pw := io.Pipe()
	scanner := bufio.NewScanner(r)
	buf := bufio.NewWriter(pw)

	go func() {
		defer func() {
			Check(pw.Close())
		}()
		defer func() {
			Check(buf.Flush())
		}()
		for scanner.Scan() {
			text := scanner.Text()
			for i := range text {
				s := make([]byte, n, n)
				for j := 0; j < n; j++ {
					s[j] = text[i]
				}
				buf.Write(s)
			}
			_, err := buf.Write([]byte{'\n'})
			Check(err)
		}
	}()
	return pr
}

func Tr(r io.Reader, m map[byte]byte) io.Reader {
	pr, pw := io.Pipe()
	r = bufio.NewReader(r)
	buf := bufio.NewWriter(pw)

	go func() {
		defer func() {
			Check(pw.Close())
		}()
		defer func() {
			Check(buf.Flush())
		}()
	loop:
		for {
			bs := make([]byte, 1)
			_, err := r.Read(bs)
			if err != nil {
				switch err {
				case io.EOF:
					break loop
				default:
					panic(err)
				}
			}
			b, ok := m[bs[0]]
			if !ok {
				b = bs[0]
			}
			buf.Write([]byte{b})
		}
	}()
	return pr
}

func BinaryChar() io.Reader {
	tr := map[byte]byte{
		'0': ' ',
		'1': '#',
	}

	r := func(r io.Reader) io.Reader {
		return Tr(r, tr)
	}(func(r io.Reader) io.Reader {
		return DoubleChars(r)
	}(func(nums []int) io.Reader {
		pr, pw := io.Pipe()
		buf := bufio.NewWriter(pw)

		go func(w io.Writer) {
			defer func() {
				Check(pw.Close())
			}()
			defer func() {
				Check(buf.Flush())
			}()
			for i := range nums {
				fmt.Fprintf(w,
					fmt.Sprintf("%%0%db\n",
						len(nums)),
					nums[i])
			}
		}(buf)

		return pr
	}(numbers)))
	return r
}
