// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';

import 'package:expect/expect.dart';

// This test implements a new special interface that can be used to
// send data more efficiently between two converters.

abstract class MyChunkedIntSink implements ChunkedConversionSink<int> {
  MyChunkedIntSink();
  factory MyChunkedIntSink.from(sink) = IntAdapterSink;
  factory MyChunkedIntSink.withCallback(callback) {
    var sink = new ChunkedConversionSink.withCallback(callback);
    return new MyChunkedIntSink.from(sink);
  }

  add(int i);
  close();

  // The special method.
  void specialI(int i);
}

class IntAdapterSink extends MyChunkedIntSink {
  final _sink;
  IntAdapterSink(this._sink);
  add(o) => _sink.add(o);
  close() => _sink.close();
  void specialI(int o) => add(o);
}

abstract class MyChunkedBoolSink implements ChunkedConversionSink<bool> {
  MyChunkedBoolSink();
  factory MyChunkedBoolSink.from(sink) = BoolAdapterSink;
  factory MyChunkedBoolSink.withCallback(callback) {
    var sink = new ChunkedConversionSink.withCallback(callback);
    return new MyChunkedBoolSink.from(sink);
  }

  add(bool b);
  close();

  specialB(bool b);
}

class BoolAdapterSink extends MyChunkedBoolSink {
  final _sink;
  BoolAdapterSink(this._sink);
  add(o) => _sink.add(o);
  close() => _sink.close();
  specialB(o) => add(o);
}

class IntBoolConverter1 extends Converter<int, bool> {
  bool convert(int input) => input > 0;

  startChunkedConversion(sink) {
    if (sink is! MyChunkedBoolSink) sink = new MyChunkedBoolSink.from(sink);
    return new IntBoolConverter1Sink(sink);
  }
}

class BoolIntConverter1 extends Converter<bool, int> {
  int convert(bool input) => input ? 1 : 0;

  startChunkedConversion(sink) {
    if (sink is! MyChunkedIntSink) sink = new MyChunkedIntSink.from(sink);
    return new BoolIntConverter1Sink(sink);
  }
}

int specialICounter = 0;
int specialBCounter = 0;

class IntBoolConverter1Sink extends MyChunkedIntSink {
  var outSink;
  IntBoolConverter1Sink(this.outSink);

  add(int i) {
    outSink.specialB(i > 0);
  }

  void specialI(int i) {
    specialICounter++;
    add(i);
  }

  close() => outSink.close();
}

class BoolIntConverter1Sink extends MyChunkedBoolSink {
  var outSink;
  BoolIntConverter1Sink(this.outSink);

  add(bool b) {
    outSink.specialI(b ? 1 : 0);
  }

  specialB(bool b) {
    specialBCounter++;
    add(b);
  }

  close() => outSink.close();
}

class IdentityConverter<T> extends Converter<T, T> {
  T convert(T x) => x;

  startChunkedConversion(sink) {
    return new IdentitySink<T>(sink);
  }
}

class IdentitySink<T> implements ChunkedConversionSink<T> {
  final _sink;
  IdentitySink(this._sink);
  void add(T o) => _sink.add(o);
  close() => _sink.close();
}

main() {
  var intSink, boolSink, sink, sink2;

  // Test int->bool converter individually.
  Converter<int, bool> int2boolConverter = new IntBoolConverter1();
  Expect.listEquals([
    true,
    false,
    true,
  ], [2, -2, 2].map(int2boolConverter.convert).toList());
  var hasExecuted = false;
  boolSink = new MyChunkedBoolSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([true, false, true], value);
  });
  intSink = int2boolConverter.startChunkedConversion(boolSink);
  intSink.add(3);
  intSink.specialI(-3);
  intSink.add(3);
  intSink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(1, specialICounter);
  specialICounter = 0;
  hasExecuted = false;

  // Test bool->int converter individually.
  Converter<bool, int> bool2intConverter = new BoolIntConverter1();
  Expect.listEquals([
    1,
    0,
    1,
  ], [true, false, true].map(bool2intConverter.convert).toList());
  hasExecuted = false;
  intSink = new MyChunkedIntSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 0, 1], value);
  });
  boolSink = bool2intConverter.startChunkedConversion(intSink);
  boolSink.specialB(true);
  boolSink.add(false);
  boolSink.add(true);
  boolSink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(1, specialBCounter);
  specialBCounter = 0;
  hasExecuted = false;

  // Test identity converter individually.
  var identityConverter = new IdentityConverter();
  hasExecuted = false;
  sink = new ChunkedConversionSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 2, 3], value);
  });
  sink2 = identityConverter.startChunkedConversion(sink);
  [1, 2, 3].forEach(sink2.add);
  sink2.close();
  Expect.isTrue(hasExecuted);
  hasExecuted = false;

  // Test fused converters.
  Converter<int, int> fused = int2boolConverter.fuse(bool2intConverter);
  Expect.listEquals([1, 0, 1], [2, -2, 2].map(fused.convert).toList());
  hasExecuted = false;
  Sink<int> intSink2 = new MyChunkedIntSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 0, 1], value);
  });
  intSink = fused.startChunkedConversion(intSink2);
  intSink.specialI(3);
  intSink.add(-3);
  intSink.add(3);
  intSink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(3, specialBCounter);
  specialBCounter = 0;
  Expect.equals(1, specialICounter);
  specialICounter = 0;
  hasExecuted = false;

  // With identity in front.
  Converter<int, int> fused2 = new IdentityConverter<int>().fuse(fused);
  hasExecuted = false;
  intSink2 = new MyChunkedIntSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 0, 1], value);
  });
  sink = fused2.startChunkedConversion(intSink2);
  Expect.isFalse(sink is MyChunkedIntSink);
  sink.add(3);
  sink.add(-3);
  sink.add(3);
  sink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(3, specialBCounter);
  specialBCounter = 0;
  Expect.equals(0, specialICounter);
  specialICounter = 0;
  hasExecuted = false;

  // With identity at the end.
  fused2 = fused.fuse(new IdentityConverter());
  hasExecuted = false;
  sink = new ChunkedConversionSink<int>.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 0, 1], value);
  });
  intSink = fused2.startChunkedConversion(sink);
  Expect.isTrue(intSink is MyChunkedIntSink);
  intSink.specialI(3);
  intSink.add(-3);
  intSink.specialI(3);
  intSink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(3, specialBCounter);
  specialBCounter = 0;
  Expect.equals(2, specialICounter);
  specialICounter = 0;
  hasExecuted = false;

  // With identity between the two converters.
  fused = int2boolConverter
      .fuse(new IdentityConverter())
      .fuse(bool2intConverter);
  Expect.listEquals([1, 0, 1], [2, -2, 2].map(fused.convert).toList());
  hasExecuted = false;
  intSink2 = new MyChunkedIntSink.withCallback((value) {
    hasExecuted = true;
    Expect.listEquals([1, 0, 1], value);
  });
  intSink = fused.startChunkedConversion(intSink2);
  intSink.specialI(3);
  intSink.add(-3);
  intSink.add(3);
  intSink.close();
  Expect.isTrue(hasExecuted);
  Expect.equals(0, specialBCounter);
  specialBCounter = 0;
  Expect.equals(1, specialICounter);
  specialICounter = 0;
  hasExecuted = false;
}
