// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/value_conversions.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "base/values.h"
#include "starboard/types.h"

namespace base {
namespace {
// Helper for serialize/deserialize UnguessableToken.
union UnguessableTokenRepresentation {
  struct Field {
    uint64_t high;
    uint64_t low;
  } field;

  uint8_t buffer[sizeof(Field)];
};
}  // namespace

// |Value| internally stores strings in UTF-8, so we have to convert from the
// system native code to UTF-8 and back.
Value CreateFilePathValue(const FilePath& in_value) {
  return Value(in_value.AsUTF8Unsafe());
}

bool GetValueAsFilePath(const Value& value, FilePath* file_path) {
  std::string str;
  if (!value.GetAsString(&str))
    return false;
  if (file_path)
    *file_path = FilePath::FromUTF8Unsafe(str);
  return true;
}

// |Value| does not support 64-bit integers, and doubles do not have enough
// precision, so we store the 64-bit time value as a string instead.
Value CreateTimeDeltaValue(const TimeDelta& time) {
  std::string string_value = base::Int64ToString(time.ToInternalValue());
  return Value(string_value);
}

bool GetValueAsTimeDelta(const Value& value, TimeDelta* time) {
  std::string str;
  int64_t int_value;
  if (!value.GetAsString(&str) || !base::StringToInt64(str, &int_value))
    return false;
  if (time)
    *time = TimeDelta::FromInternalValue(int_value);
  return true;
}

Value CreateUnguessableTokenValue(const UnguessableToken& token) {
  UnguessableTokenRepresentation representation;
  representation.field.high = token.GetHighForSerialization();
  representation.field.low = token.GetLowForSerialization();

  return Value(HexEncode(representation.buffer, sizeof(representation.buffer)));
}

bool GetValueAsUnguessableToken(const Value& value, UnguessableToken* token) {
  if (!value.is_string()) {
    return false;
  }

  // TODO(dcheng|yucliu): Make a function that accepts non vector variant and
  // reads a fixed number of bytes.
  std::vector<uint8_t> high_low_bytes;
  if (!HexStringToBytes(value.GetString(), &high_low_bytes)) {
    return false;
  }

  UnguessableTokenRepresentation representation;
  if (high_low_bytes.size() != sizeof(representation.buffer)) {
    return false;
  }

  std::copy(high_low_bytes.begin(), high_low_bytes.end(),
            std::begin(representation.buffer));
  *token = UnguessableToken::Deserialize(representation.field.high,
                                         representation.field.low);
  return true;
}

}  // namespace base
