"use strict";
var sync = require('..');
var Op = sync.Op;
var OpStream = sync.OpStream;
var bat = require('swarm-bat');
var BatStream = bat.BatStream;

var tape = require('tape');
if (typeof(window)==='object') {
    var tape_dom = require('tape-dom');
    tape_dom.installCSS();
    tape_dom.stream(tape);
}

tape('3.A simple cases', function (t) {
    var stream = new BatStream();

    var pair = new OpStream(stream.pair, 'stream', {});
    var opstream = new OpStream(stream, 'pair', {});

    var send_ops = [
        new Op('/Host#db+cluster!time1+user1~ssn.on', '', 'stream'),
        new Op('/Host#db+cluster!time2+user2~ssn.on', '12345', 'stream'),
        new Op('/Model#stamp+author!time3+user3~ssn.diff',
            '\t!stamp+source.op\tvalue\n'+
            '\t!stamp2+source2.op\tvalue2\n'+
            '\n',  // FIXME
            'stream')
    ];
    var expect_ops = [];

    t.plan(send_ops.length*3);

    opstream.on('data', function(op) {
        var next = expect_ops.pop();
        t.equal(''+op.spec, ''+next.spec, 'spec matches');
        t.equal(''+op.value, ''+next.value, 'value matches');
        t.equal(op.source, 'pair', 'source is correct');
    });

    while (send_ops.length) {
        var op = send_ops.shift();
        expect_ops.unshift(op);
        pair.write(op);
        pair.flush(); // keepalive must cause no reaction
    }
});

tape('3.B defragmentation', function (t) {
    var stream = new BatStream();
    var opstream = new OpStream(stream.pair, 'stream', {});
    var op = new Op('/Host#db+cluster!time1+user1~ssn.on', '', 'stream');
    var str = op.toString();
    t.plan(2);
    opstream.on('data', function(recv_op){
        t.equal(''+recv_op.spec, ''+op.spec, 'spec matches');
        t.equal(recv_op.value, op.value, 'value matches');
    });
    for(var i=0; i<str.length; i++) {
        stream.write(str.charAt(i));
    }
});

tape('3.C error', function (t) {
    var stream = new BatStream();
    var opstream = new OpStream(stream.pair, 'stream', {});
    t.plan(1);
    opstream.on('data', function(recv_op){
        t.ok(false, 'no ops');
    });
    opstream.on('error', function(msg) {
        t.ok(true, msg);
    });
    stream.write("!не операция\n");
});

tape('3.D handshake', function (t) {
    var stream = new BatStream();
    var opstream = new OpStream(stream.pair, undefined);
    t.plan(4);
    opstream.on('data', function(recv_op){
        t.equal(recv_op.source, 'swarm~ssn');
        t.equal(''+recv_op.spec, '/Model#stamp!time.on');
    });
    opstream.on('id', function(id, op) {
        t.equal(opstream.id, 'swarm~ssn');
        t.equal(opstream.db_id, 'db+cluster');
    });
    opstream.on('error', function(msg) {
        t.ok(false, 'no error');
    });
    stream.write("/Swarm#db+cluster!stamp+swarm~ssn.on\t\n");
    stream.write("/Model#stamp!time.on\t\n");
});

tape('3.E handshake error', function (t) {
    var stream = new BatStream();
    var opstream = new OpStream(stream.pair);
    t.plan(1);
    opstream.on('data', function(recv_op){
        t.ok(false);
    });
    opstream.on('id', function(spec) {
        t.ok(false);
    });
    opstream.on('error', function(msg) {
        t.equal(opstream.id, undefined, 'no handshake');
    });
    stream.write("/Model#stamp!time.on\t\n");
});

tape.skip('3.F stream end', function (t) {
});

@@ -2080,25 +2080,25 @@
   t.
-ok(false, 
+fail(
 'no ops
+ here
 ');%0A
@@ -2160,17 +2160,13 @@
   t.
-ok(true, 
+pass(
 msg)
@@ -2708,18 +2708,13 @@
   t.
-ok(false, 
+fail(
 'no 
@@ -2718,16 +2718,21 @@
 no error
+ here
 ');%0A    
@@ -3035,32 +3035,49 @@
 %7B%0A        t.
-ok(false
+fail('no valid data here'
 );%0A    %7D);%0A 
@@ -3128,16 +3128,34 @@
   t.
-ok(false
+fail('handshake must fail'
 );%0A 

use proper fail/pass asserts