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


#include "google_apis/drive/drive_api_parser.h"

#include <stddef.h>

#include <array>
#include <memory>
#include <string_view>

#include "base/json/json_value_converter.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "google_apis/common/parser_util.h"
#include "google_apis/common/time_util.h"

namespace google_apis {

namespace {

const int64_t kUnsetFileSize = -1;

bool CreateFileResourceFromValue(const base::Value* value,
                                 std::unique_ptr<FileResource>* file) {
  *file = FileResource::CreateFrom(*value);
  return !!*file;
}

bool CreateTeamDriveResourceFromValue(
    const base::Value* value,
    std::unique_ptr<TeamDriveResource>* file) {
  *file = TeamDriveResource::CreateFrom(*value);
  return !!*file;
}

// Converts |url_string| to |result|.  Always returns true to be used
// for JSONValueConverter::RegisterCustomField method.
// TODO(mukai): make it return false in case of invalid |url_string|.
bool GetGURLFromString(std::string_view url_string, GURL* result) {
  *result = GURL(url_string);
  return true;
}

// Converts |value| to |result|.
bool GetParentsFromValue(const base::Value* value,
                         std::vector<ParentReference>* result) {
  DCHECK(value);
  DCHECK(result);

  if (!value->is_list())
    return false;

  const base::Value::List& list = value->GetList();
  base::JSONValueConverter<ParentReference> converter;
  result->resize(list.size());
  for (size_t i = 0; i < list.size(); ++i) {
    const base::Value& parent_value = list[i];
    if (!converter.Convert(parent_value, &(*result)[i]))
      return false;
  }

  return true;
}

// Converts |value| to |result|. The key of |value| is app_id, and its value
// is URL to open the resource on the web app.
bool GetOpenWithLinksFromDictionaryValue(
    const base::Value* value,
    std::vector<FileResource::OpenWithLink>* result) {
  DCHECK(value);
  DCHECK(result);

  const auto* dict = value->GetIfDict();
  if (!dict) {
    return false;
  }

  result->reserve(dict->size());
  for (const auto item : *dict) {
    const std::string* string_value = item.second.GetIfString();
    if (!string_value)
      return false;

    FileResource::OpenWithLink open_with_link;
    open_with_link.app_id = item.first;
    open_with_link.open_url = GURL(*string_value);
    result->push_back(open_with_link);
  }

  return true;
}

// Drive v2 API JSON names.

// Definition order follows the order of documentation in
// https://developers.google.com/drive/v2/reference/

// Common
const char kLargestChangeId[] = "largestChangeId";
const char kNextPageToken[] = "nextPageToken";

// About Resource
// https://developers.google.com/drive/v2/reference/about
const char kAboutKind[] = "drive#about";
const char kQuotaBytesTotal[] = "quotaBytesTotal";
const char kQuotaBytesUsedAggregate[] = "quotaBytesUsedAggregate";
const char kRootFolderId[] = "rootFolderId";

// Parent Resource
// https://developers.google.com/drive/v2/reference/parents
const char kParentReferenceKind[] = "drive#parentReference";

// File Resource
// https://developers.google.com/drive/v2/reference/files
const char kFileKind[] = "drive#file";
const char kTitle[] = "title";
const char kMimeType[] = "mimeType";
const char kCreatedDate[] = "createdDate";
const char kModificationDate[] = "modificationDate";
const char kModifiedDate[] = "modifiedDate";
const char kModifiedByMeDate[] = "modifiedByMeDate";
const char kLastViewedByMeDate[] = "lastViewedByMeDate";
const char kSharedWithMeDate[] = "sharedWithMeDate";
const char kMd5Checksum[] = "md5Checksum";
const char kFileSize[] = "fileSize";
const char kAlternateLink[] = "alternateLink";
const char kParents[] = "parents";
const char kOpenWithLinks[] = "openWithLinks";
const char kLabels[] = "labels";
const char kImageMediaMetadata[] = "imageMediaMetadata";
const char kShared[] = "shared";
// These 5 flags are defined under |labels|.
const char kLabelTrashed[] = "trashed";
const char kLabelStarred[] = "starred";
// These 3 flags are defined under |imageMediaMetadata|.
const char kImageMediaMetadataWidth[] = "width";
const char kImageMediaMetadataHeight[] = "height";
const char kImageMediaMetadataRotation[] = "rotation";
// URL to the share dialog UI, which is provided only in v2internal.
const char kShareLink[] = "shareLink";

const char kDriveFolderMimeType[] = "application/vnd.google-apps.folder";

// Team Drive
const char kTeamDriveKind[] = "drive#teamDrive";
const char kTeamDriveListKind[] = "drive#teamDriveList";
const char kCapabilities[] = "capabilities";

// Team Drive capabilities.
// See "capabilities" in
// https://developers.google.com/drive/v2/reference/teamdrives#resource.
const char kCanAddChildren[] = "canAddChildren";
const char kCanComment[] = "canComment";
const char kCanCopy[] = "canCopy";
const char kCanDeleteTeamDrive[] = "canDeleteTeamDrive";
const char kCanDownload[] = "canDownload";
const char kCanEdit[] = "canEdit";
const char kCanListChildren[] = "canListChildren";
const char kCanManageMembers[] = "canManageMembers";
const char kCanReadRevisions[] = "canReadRevisions";
const char kCanRemoveChildren[] = "canRemoveChildren";
const char kCanRename[] = "canRename";
const char kCanRenameTeamDrive[] = "canRenameTeamDrive";
const char kCanShare[] = "canShare";

// Files List
// https://developers.google.com/drive/v2/reference/files/list
const char kFileListKind[] = "drive#fileList";
const char kNextLink[] = "nextLink";

// File Resource capabilities.
// See "capabilities" in
// https://developers.google.com/drive/v2/reference/files#resource.
const char kCanChangeRestrictedDownload[] = "canChangeRestrictedDownload";
const char kCanDelete[] = "canDelete";
const char kCanMoveItemIntoTeamDrive[] = "canMoveItemIntoTeamDrive";
const char kCanMoveTeamDriveItem[] = "canMoveTeamDriveItem";
const char kCanReadTeamDrive[] = "canReadTeamDrive";
const char kCanTrash[] = "canTrash";
const char kCanUntrash[] = "canUntrash";

// Change Resource
// https://developers.google.com/drive/v2/reference/changes
const char kChangeKind[] = "drive#change";
const char kType[] = "type";
const char kFileId[] = "fileId";
const char kDeleted[] = "deleted";
const char kFile[] = "file";
const char kTeamDrive[] = "teamDrive";
const char kTeamDriveId[] = "teamDriveId";
const char kStartPageToken[] = "startPageToken";
const char kNewStartPageToken[] = "newStartPageToken";

// Changes List
// https://developers.google.com/drive/v2/reference/changes/list
const char kChangeListKind[] = "drive#changeList";

// Maps category name to enum ChangeType.
struct ChangeTypeMap {
  ChangeResource::ChangeType type;
  const char* type_name;
};

constexpr auto kChangeTypeMap = std::to_array<ChangeTypeMap>({
    {ChangeResource::FILE, "file"},
    {ChangeResource::TEAM_DRIVE, "teamDrive"},
});

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// AboutResource implementation

AboutResource::AboutResource()
    : largest_change_id_(0),
      quota_bytes_total_(0),
      quota_bytes_used_aggregate_(0) {}

AboutResource::~AboutResource() {}

// static
std::unique_ptr<AboutResource> AboutResource::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<AboutResource> resource(new AboutResource());
  if (!IsResourceKindExpected(value, kAboutKind) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid About resource JSON!";
    return nullptr;
  }
  return resource;
}

// static
void AboutResource::RegisterJSONConverter(
    base::JSONValueConverter<AboutResource>* converter) {
  converter->RegisterCustomField<int64_t>(kLargestChangeId,
                                          &AboutResource::largest_change_id_,
                                          &base::StringToInt64);
  converter->RegisterCustomField<int64_t>(kQuotaBytesTotal,
                                          &AboutResource::quota_bytes_total_,
                                          &base::StringToInt64);
  converter->RegisterCustomField<int64_t>(
      kQuotaBytesUsedAggregate, &AboutResource::quota_bytes_used_aggregate_,
      &base::StringToInt64);
  converter->RegisterStringField(kRootFolderId,
                                 &AboutResource::root_folder_id_);
}

bool AboutResource::Parse(const base::Value& value) {
  base::JSONValueConverter<AboutResource> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid About resource JSON!";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// TeamDriveCapabilities implementation

TeamDriveCapabilities::TeamDriveCapabilities()
    : can_add_children_(false),
      can_comment_(false),
      can_copy_(false),
      can_delete_team_drive_(false),
      can_download_(false),
      can_edit_(false),
      can_list_children_(false),
      can_manage_members_(false),
      can_read_revisions_(false),
      can_remove_children_(false),
      can_rename_(false),
      can_rename_team_drive_(false),
      can_share_(false) {}

TeamDriveCapabilities::TeamDriveCapabilities(const TeamDriveCapabilities& src) =
    default;

TeamDriveCapabilities::~TeamDriveCapabilities() = default;

// static
void TeamDriveCapabilities::RegisterJSONConverter(
    base::JSONValueConverter<TeamDriveCapabilities>* converter) {
  converter->RegisterBoolField(kCanAddChildren,
                               &TeamDriveCapabilities::can_add_children_);
  converter->RegisterBoolField(kCanComment,
                               &TeamDriveCapabilities::can_comment_);
  converter->RegisterBoolField(kCanCopy, &TeamDriveCapabilities::can_copy_);
  converter->RegisterBoolField(kCanDeleteTeamDrive,
                               &TeamDriveCapabilities::can_delete_team_drive_);
  converter->RegisterBoolField(kCanDownload,
                               &TeamDriveCapabilities::can_download_);
  converter->RegisterBoolField(kCanEdit, &TeamDriveCapabilities::can_edit_);
  converter->RegisterBoolField(kCanListChildren,
                               &TeamDriveCapabilities::can_list_children_);
  converter->RegisterBoolField(kCanManageMembers,
                               &TeamDriveCapabilities::can_manage_members_);
  converter->RegisterBoolField(kCanReadRevisions,
                               &TeamDriveCapabilities::can_read_revisions_);
  converter->RegisterBoolField(kCanRemoveChildren,
                               &TeamDriveCapabilities::can_remove_children_);
  converter->RegisterBoolField(kCanRename, &TeamDriveCapabilities::can_rename_);
  converter->RegisterBoolField(kCanRenameTeamDrive,
                               &TeamDriveCapabilities::can_rename_team_drive_);
  converter->RegisterBoolField(kCanShare, &TeamDriveCapabilities::can_share_);
}

////////////////////////////////////////////////////////////////////////////////
// TeamDriveResource implementation

TeamDriveResource::TeamDriveResource() {}

TeamDriveResource::~TeamDriveResource() {}

// static
std::unique_ptr<TeamDriveResource> TeamDriveResource::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<TeamDriveResource> resource(new TeamDriveResource());
  if (!IsResourceKindExpected(value, kTeamDriveKind) ||
      !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid Team Drive resource JSON!";
    return nullptr;
  }
  return resource;
}

// static
void TeamDriveResource::RegisterJSONConverter(
    base::JSONValueConverter<TeamDriveResource>* converter) {
  converter->RegisterStringField(kApiResponseIdKey, &TeamDriveResource::id_);
  converter->RegisterStringField(kApiResponseNameKey,
                                 &TeamDriveResource::name_);
  converter->RegisterNestedField(kCapabilities,
                                 &TeamDriveResource::capabilities_);
}

bool TeamDriveResource::Parse(const base::Value& value) {
  base::JSONValueConverter<TeamDriveResource> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid Team Drive resource JSON!";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// TeamDriveList implementation

TeamDriveList::TeamDriveList() {}

TeamDriveList::~TeamDriveList() {}

// static
void TeamDriveList::RegisterJSONConverter(
    base::JSONValueConverter<TeamDriveList>* converter) {
  converter->RegisterStringField(kNextPageToken,
                                 &TeamDriveList::next_page_token_);
  converter->RegisterRepeatedMessage<TeamDriveResource>(kApiResponseItemsKey,
                                                        &TeamDriveList::items_);
}

// static
bool TeamDriveList::HasTeamDriveListKind(const base::Value& value) {
  return IsResourceKindExpected(value, kTeamDriveListKind);
}

// static
std::unique_ptr<TeamDriveList> TeamDriveList::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<TeamDriveList> resource(new TeamDriveList());
  if (!HasTeamDriveListKind(value) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid TeamDriveList JSON!";
    return nullptr;
  }
  return resource;
}

bool TeamDriveList::Parse(const base::Value& value) {
  base::JSONValueConverter<TeamDriveList> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid TeamDriveList";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// ParentReference implementation

ParentReference::ParentReference() {}

ParentReference::~ParentReference() {}

// static
void ParentReference::RegisterJSONConverter(
    base::JSONValueConverter<ParentReference>* converter) {
  converter->RegisterStringField(kApiResponseIdKey, &ParentReference::file_id_);
}

// static
std::unique_ptr<ParentReference> ParentReference::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<ParentReference> reference(new ParentReference());
  if (!IsResourceKindExpected(value, kParentReferenceKind) ||
      !reference->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid ParentRefernce JSON!";
    return nullptr;
  }
  return reference;
}

bool ParentReference::Parse(const base::Value& value) {
  base::JSONValueConverter<ParentReference> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid ParentReference";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// FileResourceCapabilities implementation

FileResourceCapabilities::FileResourceCapabilities()
    : can_add_children_(false),
      can_change_restricted_download_(false),
      can_comment_(false),
      can_copy_(false),
      can_delete_(false),
      can_download_(false),
      can_edit_(false),
      can_list_children_(false),
      can_move_item_into_team_drive_(false),
      can_move_team_drive_item_(false),
      can_read_revisions_(false),
      can_read_team_drive_(false),
      can_remove_children_(false),
      can_rename_(false),
      can_share_(false),
      can_trash_(false),
      can_untrash_(false) {}

FileResourceCapabilities::FileResourceCapabilities(
    const FileResourceCapabilities& src) = default;

FileResourceCapabilities::~FileResourceCapabilities() {}

// static
void FileResourceCapabilities::RegisterJSONConverter(
    base::JSONValueConverter<FileResourceCapabilities>* converter) {
  converter->RegisterBoolField(kCanAddChildren,
                               &FileResourceCapabilities::can_add_children_);
  converter->RegisterBoolField(
      kCanChangeRestrictedDownload,
      &FileResourceCapabilities::can_change_restricted_download_);
  converter->RegisterBoolField(kCanComment,
                               &FileResourceCapabilities::can_comment_);
  converter->RegisterBoolField(kCanCopy, &FileResourceCapabilities::can_copy_);
  converter->RegisterBoolField(kCanDelete,
                               &FileResourceCapabilities::can_delete_);
  converter->RegisterBoolField(kCanDownload,
                               &FileResourceCapabilities::can_download_);
  converter->RegisterBoolField(kCanEdit, &FileResourceCapabilities::can_edit_);
  converter->RegisterBoolField(kCanListChildren,
                               &FileResourceCapabilities::can_list_children_);
  converter->RegisterBoolField(
      kCanMoveItemIntoTeamDrive,
      &FileResourceCapabilities::can_move_item_into_team_drive_);
  converter->RegisterBoolField(
      kCanMoveTeamDriveItem,
      &FileResourceCapabilities::can_move_team_drive_item_);
  converter->RegisterBoolField(kCanReadRevisions,
                               &FileResourceCapabilities::can_read_revisions_);
  converter->RegisterBoolField(kCanReadTeamDrive,
                               &FileResourceCapabilities::can_read_team_drive_);
  converter->RegisterBoolField(kCanRemoveChildren,
                               &FileResourceCapabilities::can_remove_children_);
  converter->RegisterBoolField(kCanRename,
                               &FileResourceCapabilities::can_rename_);
  converter->RegisterBoolField(kCanShare,
                               &FileResourceCapabilities::can_share_);
  converter->RegisterBoolField(kCanTrash,
                               &FileResourceCapabilities::can_trash_);
  converter->RegisterBoolField(kCanUntrash,
                               &FileResourceCapabilities::can_untrash_);
}

////////////////////////////////////////////////////////////////////////////////
// FileResource implementation

FileResource::FileResource() : shared_(false), file_size_(kUnsetFileSize) {}

FileResource::FileResource(const FileResource& other) = default;

FileResource::~FileResource() {}

// static
void FileResource::RegisterJSONConverter(
    base::JSONValueConverter<FileResource>* converter) {
  converter->RegisterStringField(kApiResponseIdKey, &FileResource::file_id_);
  converter->RegisterStringField(kApiResponseETagKey, &FileResource::etag_);
  converter->RegisterStringField(kTitle, &FileResource::title_);
  converter->RegisterStringField(kMimeType, &FileResource::mime_type_);
  converter->RegisterNestedField(kLabels, &FileResource::labels_);
  converter->RegisterNestedField(kImageMediaMetadata,
                                 &FileResource::image_media_metadata_);
  converter->RegisterNestedField(kCapabilities, &FileResource::capabilities_);
  converter->RegisterCustomField<base::Time>(
      kCreatedDate, &FileResource::created_date_, &util::GetTimeFromString);
  converter->RegisterCustomField<base::Time>(
      kModifiedDate, &FileResource::modified_date_, &util::GetTimeFromString);
  converter->RegisterCustomField<base::Time>(
      kModifiedByMeDate, &FileResource::modified_by_me_date_,
      &util::GetTimeFromString);
  converter->RegisterCustomField<base::Time>(
      kLastViewedByMeDate, &FileResource::last_viewed_by_me_date_,
      &util::GetTimeFromString);
  converter->RegisterCustomField<base::Time>(
      kSharedWithMeDate, &FileResource::shared_with_me_date_,
      &util::GetTimeFromString);
  converter->RegisterBoolField(kShared, &FileResource::shared_);
  converter->RegisterStringField(kMd5Checksum, &FileResource::md5_checksum_);
  converter->RegisterCustomField<int64_t>(kFileSize, &FileResource::file_size_,
                                          &base::StringToInt64);
  converter->RegisterCustomField<GURL>(
      kAlternateLink, &FileResource::alternate_link_, GetGURLFromString);
  converter->RegisterCustomField<GURL>(kShareLink, &FileResource::share_link_,
                                       GetGURLFromString);
  converter->RegisterCustomValueField<std::vector<ParentReference>>(
      kParents, &FileResource::parents_, GetParentsFromValue);
  converter->RegisterCustomValueField<std::vector<OpenWithLink>>(
      kOpenWithLinks, &FileResource::open_with_links_,
      GetOpenWithLinksFromDictionaryValue);
  converter->RegisterStringField(kTeamDriveId, &FileResource::team_drive_id_);
}

// static
std::unique_ptr<FileResource> FileResource::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<FileResource> resource(new FileResource());
  if (!IsResourceKindExpected(value, kFileKind) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid FileResource JSON!";
    return nullptr;
  }
  return resource;
}

bool FileResource::IsDirectory() const {
  return mime_type_ == kDriveFolderMimeType;
}

bool FileResource::IsHostedDocument() const {
  // Hosted documents don't have fileSize field set:
  // https://developers.google.com/drive/v2/reference/files
  return !IsDirectory() && file_size_ == kUnsetFileSize;
}

bool FileResource::Parse(const base::Value& value) {
  base::JSONValueConverter<FileResource> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid FileResource";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// FileList implementation

FileList::FileList() {}

FileList::~FileList() {}

// static
void FileList::RegisterJSONConverter(
    base::JSONValueConverter<FileList>* converter) {
  converter->RegisterCustomField<GURL>(kNextLink, &FileList::next_link_,
                                       GetGURLFromString);
  converter->RegisterRepeatedMessage<FileResource>(kApiResponseItemsKey,
                                                   &FileList::items_);
}

// static
bool FileList::HasFileListKind(const base::Value& value) {
  return IsResourceKindExpected(value, kFileListKind);
}

// static
std::unique_ptr<FileList> FileList::CreateFrom(const base::Value& value) {
  std::unique_ptr<FileList> resource(new FileList());
  if (!HasFileListKind(value) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid FileList JSON!";
    return nullptr;
  }
  return resource;
}

bool FileList::Parse(const base::Value& value) {
  base::JSONValueConverter<FileList> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid FileList";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// ChangeResource implementation

ChangeResource::ChangeResource()
    : change_id_(0), type_(UNKNOWN), deleted_(false) {}

ChangeResource::~ChangeResource() {}

// static
void ChangeResource::RegisterJSONConverter(
    base::JSONValueConverter<ChangeResource>* converter) {
  converter->RegisterCustomField<int64_t>(
      kApiResponseIdKey, &ChangeResource::change_id_, &base::StringToInt64);
  converter->RegisterCustomField<ChangeType>(kType, &ChangeResource::type_,
                                             &ChangeResource::GetType);
  converter->RegisterStringField(kFileId, &ChangeResource::file_id_);
  converter->RegisterBoolField(kDeleted, &ChangeResource::deleted_);
  converter->RegisterCustomValueField(kFile, &ChangeResource::file_,
                                      &CreateFileResourceFromValue);
  converter->RegisterCustomField<base::Time>(
      kModificationDate, &ChangeResource::modification_date_,
      &util::GetTimeFromString);
  converter->RegisterStringField(kTeamDriveId, &ChangeResource::team_drive_id_);
  converter->RegisterCustomValueField(kTeamDrive, &ChangeResource::team_drive_,
                                      &CreateTeamDriveResourceFromValue);
}

// static
std::unique_ptr<ChangeResource> ChangeResource::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<ChangeResource> resource(new ChangeResource());
  if (!IsResourceKindExpected(value, kChangeKind) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid ChangeResource JSON!";
    return nullptr;
  }
  return resource;
}

bool ChangeResource::Parse(const base::Value& value) {
  base::JSONValueConverter<ChangeResource> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid ChangeResource";
    return false;
  }
  return true;
}

// static
bool ChangeResource::GetType(std::string_view type_name,
                             ChangeResource::ChangeType* result) {
  for (size_t i = 0; i < std::size(kChangeTypeMap); i++) {
    if (type_name == kChangeTypeMap[i].type_name) {
      *result = kChangeTypeMap[i].type;
      return true;
    }
  }
  DVLOG(1) << "Unknown change type" << type_name;
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// ChangeList implementation

ChangeList::ChangeList() = default;

ChangeList::~ChangeList() = default;

// static
void ChangeList::RegisterJSONConverter(
    base::JSONValueConverter<ChangeList>* converter) {
  converter->RegisterCustomField<GURL>(kNextLink, &ChangeList::next_link_,
                                       GetGURLFromString);
  converter->RegisterCustomField<int64_t>(
      kLargestChangeId, &ChangeList::largest_change_id_, &base::StringToInt64);
  converter->RegisterStringField(kNewStartPageToken,
                                 &ChangeList::new_start_page_token_);
  converter->RegisterRepeatedMessage<ChangeResource>(kApiResponseItemsKey,
                                                     &ChangeList::items_);
}

// static
bool ChangeList::HasChangeListKind(const base::Value& value) {
  return IsResourceKindExpected(value, kChangeListKind);
}

// static
std::unique_ptr<ChangeList> ChangeList::CreateFrom(const base::Value& value) {
  std::unique_ptr<ChangeList> resource(new ChangeList());
  if (!HasChangeListKind(value) || !resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid ChangeList JSON!";
    return nullptr;
  }
  return resource;
}

bool ChangeList::Parse(const base::Value& value) {
  base::JSONValueConverter<ChangeList> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid ChangeList";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// FileLabels implementation

FileLabels::FileLabels() : trashed_(false), starred_(false) {}

FileLabels::~FileLabels() {}

// static
void FileLabels::RegisterJSONConverter(
    base::JSONValueConverter<FileLabels>* converter) {
  converter->RegisterBoolField(kLabelTrashed, &FileLabels::trashed_);
  converter->RegisterBoolField(kLabelStarred, &FileLabels::starred_);
}

// static
std::unique_ptr<FileLabels> FileLabels::CreateFrom(const base::Value& value) {
  std::unique_ptr<FileLabels> resource(new FileLabels());
  if (!resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid FileLabels JSON!";
    return nullptr;
  }
  return resource;
}

bool FileLabels::Parse(const base::Value& value) {
  base::JSONValueConverter<FileLabels> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid FileLabels.";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// ImageMediaMetadata implementation

ImageMediaMetadata::ImageMediaMetadata()
    : width_(-1), height_(-1), rotation_(-1) {}

ImageMediaMetadata::~ImageMediaMetadata() {}

// static
void ImageMediaMetadata::RegisterJSONConverter(
    base::JSONValueConverter<ImageMediaMetadata>* converter) {
  converter->RegisterIntField(kImageMediaMetadataWidth,
                              &ImageMediaMetadata::width_);
  converter->RegisterIntField(kImageMediaMetadataHeight,
                              &ImageMediaMetadata::height_);
  converter->RegisterIntField(kImageMediaMetadataRotation,
                              &ImageMediaMetadata::rotation_);
}

// static
std::unique_ptr<ImageMediaMetadata> ImageMediaMetadata::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<ImageMediaMetadata> resource(new ImageMediaMetadata());
  if (!resource->Parse(value)) {
    LOG(ERROR) << "Unable to create: Invalid ImageMediaMetadata JSON!";
    return nullptr;
  }
  return resource;
}

bool ImageMediaMetadata::Parse(const base::Value& value) {
  base::JSONValueConverter<ImageMediaMetadata> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid ImageMediaMetadata.";
    return false;
  }
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// StartPageToken implementation

StartPageToken::StartPageToken() = default;

StartPageToken::~StartPageToken() = default;

// static
void StartPageToken::RegisterJSONConverter(
    base::JSONValueConverter<StartPageToken>* converter) {
  converter->RegisterStringField(kStartPageToken,
                                 &StartPageToken::start_page_token_);
}

// static
std::unique_ptr<StartPageToken> StartPageToken::CreateFrom(
    const base::Value& value) {
  std::unique_ptr<StartPageToken> result = std::make_unique<StartPageToken>();

  if (!result->Parse(value)) {
    LOG(ERROR) << "Unable to parse: Invalid StartPageToken JSON.";
    return nullptr;
  }

  return result;
}

bool StartPageToken::Parse(const base::Value& value) {
  base::JSONValueConverter<StartPageToken> converter;
  if (!converter.Convert(value, this)) {
    LOG(ERROR) << "Unable to parse: Invalid StartPageToken.";
    return false;
  }
  return true;
}

}  // namespace google_apis
