/*
<return type>         <return value>    <example>
redis_REPLY_STRING    string            "abc"
redis_REPLY_ARRAY     list of value     ["200", "300", "aaa"]
redis_REPLY_INTEGER   integer           7
redis_REPLY_NIL       []                []
redis_REPLY_STATUS    string            "OK"
redis_REPLY_ERROR     string            "ERR wrong number of arguments for 'hgetall' command"

@ If you does not want to get integer value, use redis_command_hate_integer/4.
*/

:- kanji_mode(_,off).

require(X):- redis_version(_), !.  % for built-in library case.
require(X):- dlib_require(X), !,
  write('Library Loaded: '), redis_version(V), write(V), nl.
require(X):- dlib_get_error_str(S), name(E, S), write(E), nl.

:- require(redis).

t:- 
  redis_version(VERSION),
  t(10),
  write('Version: '), w(VERSION).

t(N):-
  repeat(I),
  session,
  I1 is I + 1,
  write('--- REPEAT '), write(I1), write(' END. ---'), nl,
  I1 >= N.

session:-
  w('connect...'),
  redis_connect('127.0.0.1', 6379, 3000, CONTEXT),
  assert(used_context(CONTEXT)),
  ex_all(10, CONTEXT), !,
  %(ex(CONTEXT, ['', '', '']) -> true; true),
  (ex(CONTEXT, 'quit') -> true; true),
  w('free context...'),
  redis_free_context(CONTEXT),
  retract(used_context(CONTEXT)),
  w('end.'), !.

session:-
  retract(used_context(CONTEXT)),
  w('free context...'),
  redis_free_context(CONTEXT),
  w('end.'), !.
session:- 
  w('fail to free contex.'),
  w('end.').



ex_all(N, CONTEXT):-
  repeat(I),
  ex_all(CONTEXT),
  I1 is I + 1,
  I1 >= N.

ex_all(CONTEXT):-
  ex_single(CONTEXT),
  ex_list(CONTEXT),
  ex_hash(CONTEXT),
  ex_set(CONTEXT),
  ex_variation_of_command(CONTEXT).

ex_single(C):-
  ex(C, 'set a abcdefg'),
  ex(C, 'get a'),
  ex(C, 'set v123 12345'),
  ex(C, 'get v123'),
  ex(C, 'exists a'),
  hi(C, 'exists a').

ex_list(C):-
  ex(C, 'del v1'),
  ex(C, 'lpush v1 100'),
  ex(C, 'lpush v1 200'),
  ex(C, 'lpush v1 300'),
  ex(C, 'llen v1'),
  ex(C, 'lrange v1 0 -1').

ex_hash(C):-
  ex(C, 'del v2'),
  ex(C, 'hset v2 name 横山'),
  ex(C, 'hset v2 age  37'),
  ex(C, 'hget v2 age'),
  ex(C, 'hgetall v2').

ex_set(C):-
  ex(C, 'del v3'),
  ex(C, 'sadd v3 11'),
  ex(C, 'sadd v3 wdfght'),
  ex(C, 'sadd v3 5000000'),
  ex(C, 'sadd v3 wdfght'),
  ex(C, 'scard v3'),
  hi(C, 'scard v3'),
  ex(C, 'smembers v3').

ex_variation_of_command(C):-
  ex(C, "del v4"),
  ex(C, ['set', 'v4', '2345']),
  ex(C, ['get', 'v4']),
  ex(C, ["get", "v4"]),
  ex(C, ['get', "v4"]),
  ex(C, ['get', "vundef"]).



ex(CONTEXT, COMMAND):- exec(CONTEXT, COMMAND, 0).
hi(CONTEXT, COMMAND):- exec(CONTEXT, COMMAND, 1).

exec(CONTEXT, COMMAND, HATE_INTEGER):-
  nl,
  write('COMMAND: "'), write(COMMAND), write('"'),
  (HATE_INTEGER == 1 -> write('   (HATE INTEGER)'); true),
  nl,
  (HATE_INTEGER == 1 ->
      redis_command_hate_integer(CONTEXT, COMMAND, TYPE, VAL);
      redis_command(CONTEXT, COMMAND, TYPE, VAL)),
  write('RETURN: '), write(TYPE), nl,
  write('VAL: '), write_val_with_atom(TYPE, VAL), nl.

write_val_with_atom(redis_REPLY_ARRAY, LS):- !,
  write_array_val_with_atom(redis_REPLY_ARRAY, LS, 0).
write_val_with_atom(TYPE, LS):-
  list(LS), name(A, LS), !,
  write(LS), write(' ('), write(A), write(')').
write_val_with_atom(TYPE, LS):- write(LS).

write_array_val_with_atom(redis_REPLY_ARRAY, [], I):- nl.
write_array_val_with_atom(redis_REPLY_ARRAY, [H|LS], I):- !,
  nl, write(I), write(': '), write_val_with_atom('???', H),
  J is I + 1,
  write_array_val_with_atom(redis_REPLY_ARRAY, LS, J).

w(S):- write(S), nl.


%%%%%
test_timeout:-
  SLEEP = 38,
  redis_connect('127.0.0.1', 6379, 3000, CONTEXT),
  redis_command(CONTEXT, 'set a 100', TYPE, VAL),
  repeat(N),
    M is N + SLEEP,
    write(M), write(' sec.'), nl,
    (redis_command(CONTEXT, 'get a', T, V) ->
        (write(T), write(', '), write(V), nl);
        ((redis_is_disconnected(CONTEXT) ->
            write('disconnected');
            write('connected')), nl)
    ),
    s_sleep(M*1000),
  N == 300,
  redis_free_context(CONTEXT).


test_simple:-
  redis_connect('127.0.0.1', 6379, 3000, CONTEXT),
  redis_command(CONTEXT, ['set', '山田 正X', 'zz 123 あああ'], T1, V1),
  name(AV1, V1),
  write(T1), write(', '), write(AV1), nl,
  redis_command(CONTEXT, ['get', '山田 正X'], T2, V2),
  write(T2), write(', '), write(V2), nl,
  redis_free_context(CONTEXT).
