/*
* Naamari-lautta - a wrapper of console cloud clients for Naamari
* Copyright (c) 2015-2017 Sunkware
* Key FP = 6B6D C8E9 3438 6E9C 3D97  56E5 2CE9 A476 99EF 28F6
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* [ WWW: sunkware.org ]                         [ E-MAIL: sunkware@gmail.com ]
 */

package main

import (
	"errors"
	"io/ioutil"
)

type CryptomenData struct {
	FormatVer uint8

	IsNear   bool
	NearSalt [0x20]uint8
	NearTime int64
	NearSize int64

	IsFar   bool
	FarSalt [0x20]uint8
	FarTime int64
	FarSize int64

	Action uint8
}

const PACKED_CRYPTOMEN_DATA_SIZE = 100

func ReadCryptomenData(filePath string) (cryptomenData CryptomenData, err error) {

	var packedData []byte

	packedData, err = ioutil.ReadFile(filePath)

	if err != nil {
		err = errors.New("cannot read data from file")
		return
	}

	if len(packedData) != PACKED_CRYPTOMEN_DATA_SIZE {
		err = errors.New("wrong file size")
		return
	}

	// Uh-oh, byte tinkering...

	var slicePos int = 0
	var byteSize int

	byteSize = 1
	cryptomenData.FormatVer = SliceToUInt8(packedData[slicePos : slicePos+byteSize])
	slicePos += byteSize

	byteSize = 1
	cryptomenData.IsNear = SliceToBool(packedData[slicePos : slicePos+byteSize])
	slicePos += byteSize

	byteSize = 32
	copy(cryptomenData.NearSalt[:], packedData[slicePos:slicePos+byteSize])
	slicePos += byteSize

	byteSize = 8
	cryptomenData.NearTime = int64(SliceToUInt64(packedData[slicePos : slicePos+byteSize]))
	slicePos += byteSize

	byteSize = 8
	cryptomenData.NearSize = int64(SliceToUInt64(packedData[slicePos : slicePos+byteSize]))
	slicePos += byteSize

	byteSize = 1
	cryptomenData.IsFar = SliceToBool(packedData[slicePos : slicePos+byteSize])
	slicePos += byteSize

	byteSize = 32
	copy(cryptomenData.FarSalt[:], packedData[slicePos:slicePos+byteSize])
	slicePos += byteSize

	byteSize = 8
	cryptomenData.FarTime = int64(SliceToUInt64(packedData[slicePos : slicePos+byteSize]))
	slicePos += byteSize

	byteSize = 8
	cryptomenData.FarSize = int64(SliceToUInt64(packedData[slicePos : slicePos+byteSize]))
	slicePos += byteSize

	byteSize = 1
	cryptomenData.Action = SliceToUInt8(packedData[slicePos : slicePos+byteSize])
	slicePos += byteSize

	return
}

func WriteCryptomenData(filePath string, cryptomenData *CryptomenData) error {

	var packedData []byte = make([]byte, PACKED_CRYPTOMEN_DATA_SIZE)

	// Byte tinkering again...

	var slicePos int = 0
	var byteSize int

	byteSize = 1
	copy(packedData[slicePos:slicePos+byteSize], UInt8ToSlice(cryptomenData.FormatVer))
	slicePos += byteSize

	byteSize = 1
	copy(packedData[slicePos:slicePos+byteSize], BoolToSlice(cryptomenData.IsNear))
	slicePos += byteSize

	byteSize = 32
	copy(packedData[slicePos:slicePos+byteSize], cryptomenData.NearSalt[:])
	slicePos += byteSize

	byteSize = 8
	copy(packedData[slicePos:slicePos+byteSize], UInt64ToSlice(uint64(cryptomenData.NearTime)))
	slicePos += byteSize

	byteSize = 8
	copy(packedData[slicePos:slicePos+byteSize], UInt64ToSlice(uint64(cryptomenData.NearSize)))
	slicePos += byteSize

	byteSize = 1
	copy(packedData[slicePos:slicePos+byteSize], BoolToSlice(cryptomenData.IsFar))
	slicePos += byteSize

	byteSize = 32
	copy(packedData[slicePos:slicePos+byteSize], cryptomenData.FarSalt[:])
	slicePos += byteSize

	byteSize = 8
	copy(packedData[slicePos:slicePos+byteSize], UInt64ToSlice(uint64(cryptomenData.FarTime)))
	slicePos += byteSize

	byteSize = 8
	copy(packedData[slicePos:slicePos+byteSize], UInt64ToSlice(uint64(cryptomenData.FarSize)))
	slicePos += byteSize

	byteSize = 1
	copy(packedData[slicePos:slicePos+byteSize], UInt8ToSlice(cryptomenData.Action))
	slicePos += byteSize

	var err error

	err = ioutil.WriteFile(filePath, packedData, 0)

	if err != nil {
		return errors.New("cannot write data into file")
	}

	return nil
}
