// 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);

 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_
