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

#ifndef BIN_UTILS_H_
#define BIN_UTILS_H_

#include <stdlib.h>
#include <string.h>

#include "include/dart_api.h"
#include "platform/globals.h"

namespace dart {
namespace bin {

class OSError {
 public:
  enum SubSystem {
    kSystem,
    kGetAddressInfo,
    kBoringSSL,
    kUnknown = -1
  };

  OSError();
  OSError(int code, const char* message, SubSystem sub_system) {
    sub_system_ = sub_system;
    code_ = code;
    message_ = NULL;  // SetMessage will free existing message.
    SetMessage(message);
  }
  virtual ~OSError() { free(message_); }

  SubSystem sub_system() { return sub_system_; }
  int code() { return code_; }
  char* message() { return message_; }
  void SetCodeAndMessage(SubSystem sub_system, int code);

 private:
  void set_sub_system(SubSystem sub_system) { sub_system_ = sub_system; }
  void set_code(int code) { code_ = code; }
  void SetMessage(const char* message) {
    free(message_);
    if (message == NULL) {
      message_ = NULL;
    } else {
      message_ = strdup(message);
    }
  }

  SubSystem sub_system_;
  int code_;
  char* message_;

  DISALLOW_COPY_AND_ASSIGN(OSError);
};


class StringUtils {
 public:
  // The following methods convert the argument if needed.  The
  // conversions are only needed on Windows. If the methods returns a
  // pointer that is different from the input pointer, the returned
  // pointer is allocated with malloc and should be freed using free.
  //
  // If the len argument is passed then that number of characters are
  // converted. If len is -1, conversion will stop at the first NUL
  // character. If result_len is not NUL, it is used to set the number
  // of characters in the result.
  //
  // These conversion functions are only implemented on Windows as the
  // Dart code only hit this path on Windows.
  static const char* ConsoleStringToUtf8(const char* str,
                                         intptr_t len = -1,
                                         intptr_t* result_len = NULL);
  static char* ConsoleStringToUtf8(char* str,
                                   intptr_t len = -1,
                                   intptr_t* result_len = NULL);
  static const char* Utf8ToConsoleString(const char* utf8,
                                         intptr_t len = -1,
                                         intptr_t* result_len = NULL);
  static char* Utf8ToConsoleString(char* utf8,
                                   intptr_t len = -1,
                                   intptr_t* result_len = NULL);

  // Not all platforms support strndup.
  static char* StrNDup(const char* s, intptr_t n);

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(StringUtils);
};


class ShellUtils {
 public:
  // Convert all the arguments to UTF8. On Windows, the arguments are
  // encoded in the current code page and not UTF8.
  //
  // Returns true if the arguments are converted. In that case
  // each of the arguments need to be deallocated using free.
  static bool GetUtf8Argv(int argc, char** argv);

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ShellUtils);
};


class TimerUtils {
 public:
  static void InitOnce();
  static int64_t GetCurrentMonotonicMicros();
  static int64_t GetCurrentMonotonicMillis();
  static void Sleep(int64_t millis);

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(TimerUtils);
};

}  // namespace bin
}  // namespace dart

#endif  // BIN_UTILS_H_
