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

@JS()
library native_version_javascript;

import 'package:js/js.dart';
import 'native_version.dart';

const NativeBigIntMethods nativeBigInt = _Methods();

@JS('eval')
external Object _eval(String s);

@JS('bigint_parse')
external Object _parse(String s);

@JS('bigint_toString')
external String _toStringMethod(Object o);

@JS('bigint_bitLength')
external int _bitLength(Object o);

@JS('bigint_isEven')
external bool _isEven(Object o);

@JS('bigint_add')
external Object _add(Object left, Object right);

@JS('bigint_shiftLeft')
external Object _shiftLeft(Object o, Object i);

@JS('bigint_shiftRight')
external Object _shiftRight(Object o, Object i);

@JS('bigint_subtract')
external Object _subtract(Object left, Object right);

@JS('bigint_fromInt')
external Object _fromInt(int i);

class _Methods implements NativeBigIntMethods {
  static bool _initialized = false;
  static bool _enabled = false;

  const _Methods();

  @override
  bool get enabled {
    if (!_initialized) {
      _initialize();
    }
    return _enabled;
  }

  void _initialize() {
    _initialized = true;
    try {
      _setup();
      _enabled = true;
    } catch (e) {
      // We get here if the JavaScript implementation does not have BigInt (or
      // run in a stand-alone JavaScript implementation without the right
      // 'preamble').
      //
      // Print so we can see what failed.
      print(e);
    }
  }

  @override
  Object parse(String string) => _parse(string);

  @override
  String toStringMethod(Object value) => _toStringMethod(value);

  @override
  Object fromInt(int i) => _fromInt(i);

  @override
  Object get one => _one;

  @override
  Object get eight => _eight;

  @override
  int bitLength(Object value) => _bitLength(value);

  @override
  bool isEven(Object value) => _isEven(value);

  @override
  Object add(Object left, Object right) => _add(left, right);

  @override
  Object shiftLeft(Object value, Object count) => _shiftLeft(value, count);

  @override
  Object shiftRight(Object value, Object count) => _shiftRight(value, count);

  @override
  Object subtract(Object left, Object right) => _subtract(left, right);
}

void _setup() {
  _one = _eval('1n'); // Throws if JavaScript does not have BigInt.
  _eight = _eval('8n');

  _eval('self.bigint_parse = function parse(s) { return BigInt(s); }');
  _eval('self.bigint_toString = function toString(b) { return b.toString(); }');
  _eval('self.bigint_add = function add(a, b) { return a + b; }');
  _eval('self.bigint_shiftLeft = function shl(v, i) { return v << i; }');
  _eval('self.bigint_shiftRight = function shr(v, i) { return v >> i; }');
  _eval('self.bigint_subtract = function subtract(a, b) { return a - b; }');
  _eval('self.bigint_fromInt = function fromInt(i) { return BigInt(i); }');

  _eval('self.bigint_bitLength = function bitLength(b) {'
      'return b == 0 ? 0 : (b < 0 ? ~b : b).toString(2).length;'
      '}');
  _eval('self.bigint_isEven = function isEven(b) { return (b & 1n) == 0n; }');
}

// `dynamic` to allow null initialization pre- and post- NNBD.
dynamic _one;
dynamic _eight;
