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

import "native_testing.dart";
import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
import 'dart:_interceptors'
    show findInterceptorForType, findConstructorForNativeSubclassType;

// Test for super access from classes that extend native classes.

@Native("N1")
class N1 {}

@Native("N2")
class N2 extends N1 {
  N2.init();
  String text;
  foo() native;
}

class AA extends N2 {
  AA.init() : super.init();
  String afield;
  afun() => 'afun:$afield';
}

class BB extends AA {
  BB.init() : super.init();

  get text => super.text;
  set text(value) => super.text = value;
  foo() => super.foo();

  get afield => super.afield;
  set afield(value) => super.afield = value;
  afun() => super.afun();
}

BB makeBB() native;

@Creates('=Object')
getBBPrototype() native;

void setup() {
  JS('', r"""
(function(){
  function N2() {}
  N2.prototype.foo = function() { return "foo:" + this.text; };
  function BB() {}
  BB.prototype.__proto__ = N2.prototype;
  self.makeBB = function(){return new BB()};

  self.getBBPrototype = function(){return BB.prototype;};
})()""");
}

testSuperOnNative() {
  BB b1 = makeBB();
  BB b2 = makeBB();

  var constructor = findConstructorForNativeSubclassType(BB, 'init');
  Expect.isNotNull(constructor);
  JS('', '#(#)', constructor, b1);
  JS('', '#(#)', constructor, b2);

  b1.text = confuse('one');
  b2.text = confuse('two');

  print('b1.text ${confuse(b1).text}');
  print('b2.text ${confuse(b2).text}');

  print('b1.foo() ${confuse(b1).foo()}');
  print('b2.foo() ${confuse(b2).foo()}');

  Expect.equals('one', b1.text);
  Expect.equals('two', b2.text);

  Expect.equals('foo:one', b1.foo());
  Expect.equals('foo:two', b2.foo());

  confuse(b1).text = confuse('three');
  confuse(b2).text = confuse('four');

  Expect.equals('three', confuse(b1).text);
  Expect.equals('four', confuse(b2).text);

  Expect.equals('foo:three', confuse(b1).foo());
  Expect.equals('foo:four', confuse(b2).foo());
}

testSuperOnSubclassOfNative() {
  BB b1 = makeBB();
  BB b2 = makeBB();

  var constructor = findConstructorForNativeSubclassType(BB, 'init');
  Expect.isNotNull(constructor);
  JS('', '#(#)', constructor, b1);
  JS('', '#(#)', constructor, b2);

  b1.afield = confuse('one');
  b2.afield = confuse('two');

  print('b1.afield ${confuse(b1).afield}');
  print('b2.afield ${confuse(b2).afield}');

  print('b1.afun() ${confuse(b1).afun()}');
  print('b2.afun() ${confuse(b2).afun()}');

  Expect.equals('one', b1.afield);
  Expect.equals('two', b2.afield);

  Expect.equals('afun:one', b1.afun());
  Expect.equals('afun:two', b2.afun());

  confuse(b1).afield = confuse('three');
  confuse(b2).afield = confuse('four');

  Expect.equals('three', confuse(b1).afield);
  Expect.equals('four', confuse(b2).afield);

  Expect.equals('afun:three', confuse(b1).afun());
  Expect.equals('afun:four', confuse(b2).afun());
}

main() {
  nativeTesting();
  setup();

  setNativeSubclassDispatchRecord(getBBPrototype(), findInterceptorForType(BB));

  testSuperOnNative();
  testSuperOnSubclassOfNative();
}
