// hash_mona.go
package mona

/*
#cgo CFLAGS : -I../include
#cgo LDFLAGS: -L../lib -llyra2re

#include <stdio.h>
#include <stdlib.h>
#include "Lyra2RE.h"
*/
import "C"

import (
	"bytes"
	//"encoding/hex"
	"log"
	"unsafe"

	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/wire"
)

// MONA
func Build_MonaPowHash(h wire.BlockHeader) chainhash.Hash {
	outputs := make([]byte, 32)
	var powhash chainhash.Hash
	buf := bytes.NewBuffer(make([]byte, 0, wire.MaxBlockHeaderPayload))
	err := h.Serialize(buf)
	if err != nil {
		log.Println("[mona] powhash: Serialize error:", err)
		return powhash
	}
	//test_mona_pow := "0000002013bea8369753c2a405f4704f698f7322c0a52f3ab89e853a14c3b124cf667d098612a82ce1741ab44ae31b5aeb6a7e622386cc4baeb57a046ed1d0fa676fee6cd0f008678ef70f1a6e9deb7a"
	//test_mona_bytes, _ := hex.DecodeString(test_mona_pow)

	//log.Println("[mona]in", hex.EncodeToString(buf.Bytes()))
	in := (*C.char)(C.CBytes(buf.Bytes()))
	//in := (*C.char)(C.CBytes(test_mona_bytes))
	defer C.free(unsafe.Pointer(in))

	output := (*C.char)(C.malloc(32))
	if output == nil {
		log.Println("[mona] powhash: malloc failed")
		return powhash
	}
	defer C.free(unsafe.Pointer(output))

	//C.lyra2re2_hash(unsafe.Pointer(in), unsafe.Pointer(output))
	C.lyra2re2_hash(in, output)
	//outputs := C.GoBytes((*C.uint8_t)((unsafe.Pointer)(output)), 32)
	/*p := uintptr(unsafe.Pointer(output))
	for i := 0; i < 32; i++ {
		j := *(*byte)(unsafe.Pointer(p))
		outputs[i] = j
		p += unsafe.Sizeof(j)
	}*/
	outputs = C.GoBytes(unsafe.Pointer(output), 32)
	//log.Println("[mona]out", outputs)

	err = powhash.SetBytes(outputs)
	if err != nil {
		log.Println("[mona] powhash: SetBytes error:", err)
		return powhash
	}
	return powhash
}