"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cids_1 = __importDefault(require("cids"));
const loglevel_1 = __importDefault(require("loglevel"));
const threads_core_1 = require("@textile/threads-core");
const coding_1 = require("./coding");
const logger = loglevel_1.default.getLogger('encoding:record');
/**
 * CreateRecord returns a new record from the given block and log private key.
 * @param data Input Event data.
 * @param config A set of key/CID options for creating the new record.
 * @param opts Additional encoding/encryption options.
 */
function createRecord(data, config, opts = coding_1.defaultOptions) {
    return __awaiter(this, void 0, void 0, function* () {
        logger.debug('creating record');
        const block = yield data.value.cid();
        let payload = block.buffer;
        const pubKey = config.pubKey.bytes;
        if (config.prev && cids_1.default.isCID(config.prev)) {
            payload = Buffer.concat([payload, config.prev.buffer]);
        }
        else {
            payload = pubKey;
        }
        const sig = yield config.privKey.sign(payload);
        const obj = {
            block,
            sig,
            pubKey,
        };
        // Don't include prev unless it is defined
        if (config.prev)
            obj.prev = config.prev;
        const node = threads_core_1.Block.encoder(obj, opts.codec, opts.algo);
        const value = coding_1.encodeBlock(node, config.servKey, opts);
        // @todo: We don't support a dag here yet, but this is where we'd add this data to IPFS!
        const record = {
            value,
            obj,
            block: data,
        };
        return record;
    });
}
exports.createRecord = createRecord;
/**
 * RecordToProto returns a proto version of a record for transport. Nodes are sent encrypted.
 * @param rec The input record to encode as a protobuf-like object.
 */
function recordToProto(rec) {
    logger.debug('converting log record to proto object');
    const event = rec.block;
    const eventnode = event.value.encodeUnsafe().toString('base64');
    const headernode = event.header.encodeUnsafe().toString('base64');
    const bodynode = event.body.encodeUnsafe().toString('base64');
    const recordnode = rec.value.encodeUnsafe().toString('base64');
    const record = {
        eventnode,
        headernode,
        bodynode,
        recordnode,
    };
    return record;
}
exports.recordToProto = recordToProto;
/**
 * RecordFromProto returns a node from a serialized version that contains link data.
 * @param proto The input protobuf-like object.
 * @param key The symmetric key.
 * @param opts Additional encoding/encryption options.
 */
function recordFromProto(proto, key, opts = coding_1.defaultOptions) {
    logger.debug('converting proto object to log record');
    const rawRecord = Buffer.from(proto.recordnode, 'base64');
    const rnode = threads_core_1.Block.decoder(rawRecord, opts.codec, opts.algo);
    const rawEvent = Buffer.from(proto.eventnode, 'base64');
    const enode = threads_core_1.Block.decoder(rawEvent, opts.codec, opts.algo);
    const rawHeader = Buffer.from(proto.headernode, 'base64');
    const hnode = threads_core_1.Block.decoder(rawHeader, opts.codec, opts.algo);
    const rawBody = Buffer.from(proto.bodynode, 'base64');
    const body = threads_core_1.Block.decoder(rawBody, opts.codec, opts.algo);
    const decoded = coding_1.decodeBlock(rnode, key);
    const robj = decoded.decode();
    const eobj = enode.decode();
    enode.encode(); // Created encoded value
    body.encode();
    hnode.encode();
    const evt = {
        value: enode,
        header: hnode,
        body: body,
        obj: eobj,
    };
    const rec = {
        value: rnode,
        obj: robj,
        block: evt,
    };
    return rec;
}
exports.recordFromProto = recordFromProto;
//# sourceMappingURL=record.js.map