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

#include <ctype.h>  // isspace.

#include "vm/bootstrap_natives.h"

#include "vm/bigint_operations.h"
#include "vm/exceptions.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/random.h"
#include "vm/scanner.h"
#include "vm/symbols.h"

namespace dart {

DEFINE_NATIVE_ENTRY(MathNatives_sqrt, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(sqrt(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_sin, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(sin(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_cos, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(cos(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_tan, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(tan(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_asin, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(asin(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_acos, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(acos(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_atan, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(atan(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_atan2, 2) {
  GET_NATIVE_ARGUMENT(Double, operand1, arguments->At(0));
  GET_NATIVE_ARGUMENT(Double, operand2, arguments->At(1));
  return Double::New(atan2(operand1.value(), operand2.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_exp, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(exp(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_log, 1) {
  GET_NATIVE_ARGUMENT(Double, operand, arguments->At(0));
  return Double::New(log(operand.value()));
}

DEFINE_NATIVE_ENTRY(MathNatives_random, 0) {
  return Double::New(static_cast<double>(Random::RandomInt32()-1)/0x80000000);
}


// TODO(srdjan): Investigate for performance hit; the integer and double parsing
// may not be efficient as we need to generate two extra growable arrays.
static bool IsValidLiteral(const Scanner::GrowableTokenStream& tokens,
                           Token::Kind literal_kind,
                           bool* is_positive,
                           String** value) {
  if ((tokens.length() == 2) &&
      (tokens[0].kind == literal_kind) &&
      (tokens[1].kind == Token::kEOS)) {
    *is_positive = true;
    *value = tokens[0].literal;
    return true;
  }
  if ((tokens.length() == 3) &&
      ((tokens[0].kind == Token::kTIGHTADD) ||
          (tokens[0].kind == Token::kSUB)) &&
      (tokens[1].kind == literal_kind) &&
      (tokens[2].kind == Token::kEOS)) {
    // Check there is no space between "+/-" and number.
    if ((tokens[0].offset + 1) != tokens[1].offset) {
      return false;
    }
    *is_positive = tokens[0].kind == Token::kTIGHTADD;
    *value = tokens[1].literal;
    return true;
  }
  return false;
}


DEFINE_NATIVE_ENTRY(MathNatives_parseInt, 1) {
  GET_NATIVE_ARGUMENT(String, value, arguments->At(0));
  const String& dummy_key = String::Handle(Symbols::Empty());
  Scanner scanner(value, dummy_key);
  const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
  String* int_string;
  bool is_positive;
  if (IsValidLiteral(tokens, Token::kINTEGER, &is_positive, &int_string)) {
    if (is_positive) {
      return Integer::New(*int_string);
    } else {
      String& temp = String::Handle();
      temp = String::Concat(String::Handle(Symbols::New("-")),
                            *int_string);
      return Integer::New(temp);
    }
  } else {
    GrowableArray<const Object*> args;
    args.Add(&value);
    Exceptions::ThrowByType(Exceptions::kFormat, args);
    return Object::null();
  }
}


DEFINE_NATIVE_ENTRY(MathNatives_parseDouble, 1) {
  GET_NATIVE_ARGUMENT(String, value, arguments->At(0));
  const String& dummy_key = String::Handle(Symbols::Empty());
  Scanner scanner(value, dummy_key);
  const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
  String* number_string;
  bool is_positive;
  if (IsValidLiteral(tokens, Token::kDOUBLE, &is_positive, &number_string)) {
    const char* cstr = number_string->ToCString();
    char* p_end = NULL;
    double double_value = strtod(cstr, &p_end);
    ASSERT(p_end != cstr);
    if (!is_positive) {
      double_value = -double_value;
    }
    return Double::New(double_value);
  }

  if (IsValidLiteral(tokens, Token::kINTEGER, &is_positive, &number_string)) {
    Integer& res = Integer::Handle(Integer::New(*number_string));
    if (is_positive) {
      return Double::New(res.AsDoubleValue());
    } else {
      return Double::New(-res.AsDoubleValue());
    }
  }

  // Infinity and nan.
  if (IsValidLiteral(tokens, Token::kIDENT, &is_positive, &number_string)) {
    if (number_string->Equals("NaN")) {
      return Double::New(NAN);
    }
    if (number_string->Equals("Infinity")) {
      if (is_positive) {
        return Double::New(INFINITY);
      } else {
        return Double::New(-INFINITY);
      }
    }
  }

  GrowableArray<const Object*> args;
  args.Add(&value);
  Exceptions::ThrowByType(Exceptions::kFormat, args);
  return Object::null();
}

}  // namespace dart
