:- use_module(library(protobufs)).
:- use_module(library(lists)).

wirestream(Codes) :-
    Codes = [82,9,105,110,112,117,116,84,121,112,101].

%  ?- wirestream(Codes), disect_wire_type(W1, Codes),
%     testit(codes(X)), disect_wire_type(W2, X).
%
% Codes = [82, 9, 105, 110, 112, 117, 116, 84, 121, 112, 101],
%  W1 = wire_type(10, length_delimited, [9, 105, 110, 112, 117, 116, 84,
% 121, 112, 101]),
% X = [105, 110, 112, 117, 116, 84, 121, 112, 101],
% W2 = wire_type(13, fixed64, [110, 112, 117, 116, 84, 121, 112, 101]).

/*
*/

numeric_alternative(integer64(X), Proto) :-
    Proto   = protobuf([ integer64(13, X)]).

numeric_alternative(integer(X), Proto) :-
    Proto = protobuf([integer(13, X)]).

numeric_alternative(double(X), Proto) :-
    Proto   = protobuf([ double(13, X)]).

/*
*/

alternative(X, Proto) :-
    numeric_alternative(X, Payload),
    Proto   = protobuf([embedded(10, Payload)]).

alternative(string(X), Proto) :-
    Proto   = protobuf([string(10, X)]).

alternative(codes(X), Proto) :-
    Proto   = protobuf([codes(10, X)]).

alternative(atom(X), Proto) :-
    Proto   = protobuf([atom(10, X)]).

/*
*/

testit(X) :-
    wirestream(Codes),

    alternative(X, Proto),

    protobuf_message(Proto, Codes).


testall :-
    forall(testit(X),
	   (   print(X), nl)).


test_permutation([], []) :- !.

test_permutation([P1 | More], Codes) :-
    alternative(P1, Proto),

    protobuf_message(Proto, Codes, Residue),

    test_permutation(More, Residue).


testit_permuted(Y) :-
    wirestream(Codes),

    append(Codes, Codes, Codes2),
    append(Codes, Codes2, Codes3), !,

    writeln(Codes3),

    permutation([double(_), integer64(_), string(_)], Y),

    test_permutation(Y, Codes3).

