// Copyright (c) 2012, 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.

// VMOptions=--enable-isolate-groups --no-enable-fast-object-copy
// VMOptions=--enable-isolate-groups --enable-fast-object-copy
// VMOptions=--no-enable-isolate-groups

// Dart test program for testing serialization of messages.
// VMOptions=--enable_type_checks --enable_asserts --enable-isolate-groups
// VMOptions=--enable_type_checks --enable_asserts --no-enable-isolate-groups

library MessageTest;

import 'dart:async';
import 'dart:collection';
import 'dart:io';
import 'dart:isolate';

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'dart:typed_data';

final bool isolateGroupsEnabled =
    Platform.executableArguments.contains('--enable-isolate-groups');

void echoMain(msg) {
  SendPort replyTo = msg[0];
  SendPort pong = msg[1];
  ReceivePort port = new ReceivePort();
  replyTo.send(port.sendPort);
  port.listen((msg) {
    if (msg == "halt") {
      port.close();
    } else {
      pong.send(msg);
    }
  });
}

class A {
  var field = 499;

  A();
  A.named(this.field);
}

class B extends A {
  final field2;
  B() : field2 = 99;
  B.named(this.field2, x) : super.named(x);
}

class C extends B {
  var field = 33;

  get superField => super.field;
  get superField2 => super.field2;
}

class M {
  get field2 => 11;
}

class D extends C with M {
  var gee = 123;
}

class E {
  // Make sure E.fun is not removed by the tree shaker, as this test verifies
  // that an object with a tear-off in E.fun cannot be sent.
  @pragma("vm:entry-point")
  Function fun;

  E(this.fun);

  static fooFun() => 499;
  instanceFun() => 1234;
}

barFun() => 42;

class F {
  final field = "field";
  const F();
}

class G {
  final field;
  const G(this.field);
}

class Value {
  final val;
  Value(this.val);

  operator ==(other) {
    if (other is! Value) return false;
    return other.val == val;
  }

  get hashCode => val;
}

void runTests(SendPort ping, Queue checks) {
  ping.send("abc");
  checks.add((x) => Expect.equals("abc", x));

  ping.send([1, 2]);
  checks.add((x) {
    Expect.isTrue(x is List);
    Expect.listEquals([1, 2], x);
    // Make sure the list is mutable.
    x[0] = 0;
    Expect.equals(0, x[0]);
    // List must be extendable.
    x.add(3);
    Expect.equals(3, x[2]);
  });

  var fixed = List.filled(2, 0);
  fixed[0] = 0;
  fixed[1] = 1;
  ping.send(fixed);
  checks.add((x) {
    Expect.isTrue(x is List);
    Expect.listEquals([0, 1], x);
    // List must be mutable.
    x[0] = 3;
    Expect.equals(3, x[0]);
    // List must be fixed length.
    Expect.throws(() {
      x.add(5);
    });
  });

  List cyclic = [];
  cyclic.add(cyclic);
  ping.send(cyclic);
  checks.add((x) {
    Expect.isTrue(x is List);
    Expect.equals(1, x.length);
    Expect.identical(x, x[0]);
    // List must be mutable.
    x[0] = 55;
    Expect.equals(55, x[0]);
    // List must be extendable.
    x.add(42);
    Expect.equals(42, x[1]);
  });

  var cyclic2 = List<Object?>.filled(1, null);
  cyclic2[0] = cyclic2;
  ping.send(cyclic2);
  checks.add((x) {
    Expect.isTrue(x is List);
    Expect.equals(1, x.length);
    Expect.identical(x, x[0]);
    // List must be mutable.
    x[0] = 55;
    Expect.equals(55, x[0]);
    // List must be fixed.
    Expect.throws(() => x.add(42));
  });

  List constList = const [1, 2];
  ping.send(constList);
  checks.add((x) {
    Expect.isTrue(x is List);
    Expect.listEquals([1, 2], x);
    // Make sure the list is immutable.
    Expect.throws(() => x[0] = 0); // //# constList: ok
    // List must not be extendable.
    Expect.throws(() => x.add(3));
    Expect.identical(x, constList); // //# constList_identical: ok
  });

  Uint8List uint8 = new Uint8List(2);
  uint8[0] = 0;
  uint8[1] = 1;
  ping.send(uint8);
  checks.add((x) {
    Expect.isTrue(x is Uint8List);
    Expect.equals(2, x.length);
    Expect.equals(0, x[0]);
    Expect.equals(1, x[1]);
  });

  Uint16List uint16 = new Uint16List(2);
  uint16[0] = 0;
  uint16[1] = 1;
  ByteBuffer byteBuffer = uint16.buffer;
  ping.send(byteBuffer); // //# byteBuffer: ok
  checks.add( //            //# byteBuffer: ok
  (x) {
    Expect.isTrue(x is ByteBuffer);
    Uint16List uint16View = new Uint16List.view(x);
    Expect.equals(2, uint16View.length);
    Expect.equals(0, uint16View[0]);
    Expect.equals(1, uint16View[1]);
  }
  ) //                      //# byteBuffer: ok
      ;

  Int32x4List list32x4 = new Int32x4List(2);
  list32x4[0] = new Int32x4(1, 2, 3, 4);
  list32x4[1] = new Int32x4(5, 6, 7, 8);
  ping.send(list32x4);
  checks.add(
  (x) {
    Expect.isTrue(x is Int32x4List);
    Expect.equals(2, x.length);
    Int32x4 entry1 = x[0];
    Int32x4 entry2 = x[1];
    Expect.equals(1, entry1.x);
    Expect.equals(2, entry1.y);
    Expect.equals(3, entry1.z);
    Expect.equals(4, entry1.w);
    Expect.equals(5, entry2.x);
    Expect.equals(6, entry2.y);
    Expect.equals(7, entry2.z);
    Expect.equals(8, entry2.w);
  });

  Float32x4List flist32x4 = new Float32x4List(2);
  flist32x4[0] = new Float32x4(1.5, 2.5, 3.5, 4.5);
  flist32x4[1] = new Float32x4(5.5, 6.5, 7.5, 8.5);
  ping.send(flist32x4);
  checks.add(
  (x) {
    Expect.isTrue(x is Float32x4List);
    Expect.equals(2, x.length);
    Float32x4 entry1 = x[0];
    Float32x4 entry2 = x[1];
    Expect.equals(1.5, entry1.x);
    Expect.equals(2.5, entry1.y);
    Expect.equals(3.5, entry1.z);
    Expect.equals(4.5, entry1.w);
    Expect.equals(5.5, entry2.x);
    Expect.equals(6.5, entry2.y);
    Expect.equals(7.5, entry2.z);
    Expect.equals(8.5, entry2.w);
  });

  Float64x2List flist64x2 = new Float64x2List(2);
  flist64x2[0] = new Float64x2(1.5, 2.5);
  flist64x2[1] = new Float64x2(5.5, 6.5);
  ping.send(flist64x2);
  checks.add(
  (x) {
    Expect.isTrue(x is Float64x2List);
    Expect.equals(2, x.length);
    Float64x2 entry1 = x[0];
    Float64x2 entry2 = x[1];
    Expect.equals(1.5, entry1.x);
    Expect.equals(2.5, entry1.y);
    Expect.equals(5.5, entry2.x);
    Expect.equals(6.5, entry2.y);
  });

  ping.send({"foo": 499, "bar": 32});
  checks.add((x) {
    Expect.isTrue(x is LinkedHashMap);
    Expect.listEquals(["foo", "bar"], x.keys.toList());
    Expect.listEquals([499, 32], x.values.toList());
    Expect.equals(499, x["foo"]);
    Expect.equals(32, x["bar"]);
    // Must be mutable.
    x["foo"] = 22;
    Expect.equals(22, x["foo"]);
    // Must be extendable.
    x["gee"] = 499;
    Expect.equals(499, x["gee"]);
  });

  Map<String, int> mapWithRemovedKey = {"foo": 499, "bar": 32};
  mapWithRemovedKey.remove("foo");
  ping.send(mapWithRemovedKey);
  checks.add((x) {
    Expect.isTrue(x is LinkedHashMap);
    Expect.listEquals(["bar"], x.keys.toList());
    Expect.listEquals([32], x.values.toList());
    Expect.equals(32, x["bar"]);
  });

  // Test map where a key does not define ==/hashCode.
  Map<A, int> mapWithIdentityKey = new Map<A, int>();
  mapWithIdentityKey[new A()] = 499;
  ping.send(mapWithIdentityKey);
  checks.add((x) {
    Expect.isTrue(x is LinkedHashMap);
    int value = x.values.first;
    Expect.equals(499, value);
    A key = x.keys.first;
    Expect.equals(499, x[key]);
  });

  ping.send({0: 499, 1: 32});
  checks.add((x) {
    Expect.isTrue(x is LinkedHashMap);
    Expect.listEquals([0, 1], x.keys.toList());
    Expect.listEquals([499, 32], x.values.toList());
    // Must be mutable.
    x[0] = 22;
    Expect.equals(22, x[0]);
    // Must be extendable.
    x[123] = 499;
    Expect.equals(499, x[123]);
  });

  Map cyclicMap = {};
  cyclicMap["cycle"] = cyclicMap;
  ping.send(cyclicMap);
  checks.add((x) {
    Expect.isTrue(x is LinkedHashMap);
    Expect.identical(x, x["cycle"]);
    // Must be mutable.
    x["cycle"] = 22;
    Expect.equals(22, x["cycle"]);
    // Must be extendable.
    x["gee"] = 499;
    Expect.equals(499, x["gee"]);
  });

  Map constMap = const {'foo': 499};
  ping.send(constMap);
  checks.add((x) {
    Expect.isTrue(x is Map);
    print(x.length);
    Expect.equals(1, x.length);
    Expect.equals(499, x['foo']);
    Expect.identical(constMap, x); // //# constMap: ok
    Expect.throws(() => constMap['bar'] = 42);
  });

  ping.send(new A());
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.equals(499, x.field);
  });

  ping.send(new A.named(42));
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.equals(42, x.field);
  });

  ping.send(new B());
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.isTrue(x is B);
    Expect.equals(499, x.field);
    Expect.equals(99, x.field2);
    Expect.throws(() => x.field2 = 22);
  });

  ping.send(new B.named(1, 2));
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.isTrue(x is B);
    Expect.equals(2, x.field);
    Expect.equals(1, x.field2);
    Expect.throws(() => x.field2 = 22);
  });

  ping.send(new C());
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.isTrue(x is B);
    Expect.isTrue(x is C);
    Expect.equals(33, x.field);
    Expect.equals(99, x.field2);
    Expect.equals(499, x.superField);
    Expect.throws(() => x.field2 = 22);
  });

  ping.send(new D());
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.isTrue(x is B);
    Expect.isTrue(x is C);
    Expect.isTrue(x is D);
    Expect.isTrue(x is M);
    Expect.equals(33, x.field);
    Expect.equals(11, x.field2);
    Expect.equals(499, x.superField);
    Expect.equals(99, x.superField2);
    Expect.throws(() => x.field2 = 22);
  });

  D cyclicD = new D();
  ping.send(cyclicD);
  checks.add((x) {
    Expect.isTrue(x is A);
    Expect.isTrue(x is B);
    Expect.isTrue(x is C);
    Expect.isTrue(x is D);
    Expect.isTrue(x is M);
    Expect.equals(11, x.field2);
    Expect.equals(499, x.superField);
    Expect.equals(99, x.superField2);
    Expect.throws(() => x.field2 = 22);
  });

  ping.send(new E(E.fooFun)); //       //# fun: ok
  checks.add((x) { //                  //# fun: continued
    Expect.equals(E.fooFun, x.fun); // //# fun: continued
    Expect.equals(499, x.fun()); //    //# fun: continued
  }); //                               //# fun: continued

  ping.send(new E(barFun)); //         //# fun: continued
  checks.add((x) { //                  //# fun: continued
    Expect.equals(barFun, x.fun); //   //# fun: continued
    Expect.equals(42, x.fun()); //     //# fun: continued
  }); //                               //# fun: continued

  if (isolateGroupsEnabled) {
    ping.send(new E(new E(E.fooFun).instanceFun));
    checks.add((x) {
      Expect.equals(1234, (x as E).fun());
    });
  } else {
    Expect.throws(() => ping.send(new E(new E(E.fooFun).instanceFun)));
  }

  F nonConstF = new F();
  ping.send(nonConstF);
  checks.add((x) {
    Expect.equals("field", x.field);
    Expect.isFalse(identical(nonConstF, x));
  });

  const F constF = const F();
  ping.send(constF);
  checks.add((x) {
    Expect.equals("field", x.field);
    Expect.identical(constF, x); // //# constInstance: ok
  });

  G g1 = new G(nonConstF);
  G g2 = new G(constF);
  G g3 = const G(constF);
  ping.send(g1);
  ping.send(g2);
  ping.send(g3);

  checks.add((x) {
    // g1.
    Expect.isTrue(x is G);
    Expect.isFalse(identical(g1, x));
    F f = x.field;
    Expect.equals("field", f.field);
    Expect.isFalse(identical(nonConstF, f));
  });
  checks.add((x) {
    // g2.
    Expect.isTrue(x is G);
    Expect.isFalse(identical(g1, x));
    F f = x.field;
    Expect.equals("field", f.field);
    Expect.identical(constF, f); // //# constInstance: continued
  });
  checks.add((x) {
    // g3.
    Expect.isTrue(x is G);
    Expect.identical(g3, x); // //# constInstance: continued
    F f = x.field;
    Expect.equals("field", f.field);
    Expect.identical(constF, f); // //# constInstance: continued
  });

  // Make sure objects in a map are serialized and deserialized in the correct
  // order.
  Map m = new Map();
  Value val1 = new Value(1);
  Value val2 = new Value(2);
  m[val1] = val2;
  m[val2] = val1;
  // Possible bug we want to catch:
  // serializer runs through keys first, and then the values:
  //    - id1 = val1, id2 = val2, ref[id2], ref[id1]
  // deserializer runs through the keys and values in order:
  //    - val1;  // id1.
  //    - ref[id2];  // boom. Wasn't deserialized yet.
  ping.send(m);
  checks.add((x) {
    Expect.isTrue(x is Map);
    Expect.equals(2, x.length);
    Expect.equals(val2, x[val1]);
    Expect.equals(val1, x[val2]);
    Expect.identical(x.keys.elementAt(0), x.values.elementAt(1));
    Expect.identical(x.keys.elementAt(1), x.values.elementAt(0));
  });
}

void main() {
  asyncStart();
  Queue checks = new Queue();
  ReceivePort testPort = new ReceivePort();
  Completer completer = new Completer();

  testPort.listen((msg) {
    Function check = checks.removeFirst();
    check(msg);
    if (checks.isEmpty) {
      completer.complete();
      testPort.close();
    }
  });

  ReceivePort initialReplyPort = new ReceivePort();
  Isolate
      .spawn(echoMain, [initialReplyPort.sendPort, testPort.sendPort])
      .then((_) => initialReplyPort.first)
      .then((_ping) {
        SendPort ping = _ping;
        runTests(ping, checks);
        Expect.isTrue(checks.length > 0);
        completer.future.then((_) => ping.send("halt")).then((_) => asyncEnd());
      });
}
