package chain

import (
	"encoding/hex"
	"fmt"
	"golang.org/x/crypto/sha3"
	"math/rand"
)

type block struct {
	Transactions []transaction
	HashPrevious []byte
	Nonce        []byte
}

func NewBlock(hashPrevious []byte) block {
	return block{
		Transactions: nil,
		HashPrevious: hashPrevious,
	}
}

func (b *block) AddTransaction(t transaction) {
	b.Transactions = append(b.Transactions, t)
}

func (b block) GenerateHash(difficulty int) []byte {
	found := false
	var compBytes []byte
	var compString string
	for i := 0; i < difficulty; i++ {
		compBytes = append(compBytes, []byte("0x00")...)
	}
	for i := 0; i < difficulty; i++ {
		compString += "0"
	}
	for !found {
		random := make([]byte, 64)
		rand.Read(random)
		b.Nonce = random

		hasher := sha3.New512()
		hasher.Write(b.ToBytes())
		hash := hasher.Sum(nil)
		//if checkAllZero(XorSlice(hash[:difficulty], compBytes)) {
		hexstring := hex.EncodeToString(hash)
		fmt.Printf("%x\n", hash)
		if hexstring[:difficulty] == compString {
			return hash
		}
	}
	return nil
}

func (b block) ToBytes() []byte {
	var bytes []byte
	for i := 0; i < len(b.Transactions); i++ {
		bytes = append(bytes, b.Transactions[i].ToBytes()...)
	}
	bytes = append(bytes, b.HashPrevious...)
	bytes = append(bytes, b.Nonce...)
	return bytes
}

func XorSlice(a []byte, b []byte) []byte {
	for i := range a {
		a[i] = a[i] ^ b[i]
	}
	return a
}

func checkAllZero(a []byte) bool {
	for i, _ := range a {
		if a[i] != 0x00 {
			return false
		}
	}
	return true
}
