// 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.

// @dart = 2.9

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 extends 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 extends 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> extends 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;
}
