package dev.photosync.core.provider.google;

import java.util.List;

/**
 * The slices of the Google Photos Library API v1 that PhotoSync reads, mirrored
 * as records for Gson.
 *
 * <p>The API is camelCase throughout, so these need no name mapping. Two of its
 * conventions do need remembering, and both are why several fields below are
 * {@code String} where a number would be expected:
 *
 * <ul>
 *   <li>Google's JSON encodes every 64-bit integer as a string, so
 *       {@code mediaItemsCount} arrives as {@code "42"}.</li>
 *   <li>{@code width} and {@code height} are documented the same way, even
 *       though no photo is 2^53 pixels wide.</li>
 * </ul>
 *
 * <p>Fields the mod does not use are simply absent; Gson ignores unknown JSON
 * members, and the smaller this file is the fewer ways an API change breaks us.
 */
final class GoogleDtos {

    private GoogleDtos() {
    }

    /**
     * One photo or video.
     *
     * <p>{@code baseUrl} is the only way to get pixels, it is not a stable
     * identifier, and it stops working roughly an hour after it was issued --
     * see {@code GooglePhotosProvider#thumbnail}.
     */
    record MediaItem(
            String id,
            String description,
            String baseUrl,
            String mimeType,
            String filename,
            MediaMetadata mediaMetadata) {
    }

    /** {@code creationTime} is RFC 3339 in UTC; the width and height are decimal strings. */
    record MediaMetadata(String creationTime, String width, String height) {
    }

    record MediaItemsResponse(List<MediaItem> mediaItems, String nextPageToken) {
    }

    /** Body for {@code mediaItems:search}. Only set the fields being used; nulls are omitted by Gson. */
    record SearchRequest(String albumId, Integer pageSize, String pageToken) {
    }

    record AlbumSummary(String id, String title, String mediaItemsCount, String coverPhotoMediaItemId) {
    }

    record AlbumsResponse(List<AlbumSummary> albums, String nextPageToken) {
    }

    record CreateAlbumRequest(NewAlbum album) {
    }

    record NewAlbum(String title) {
    }

    record BatchCreateRequest(String albumId, List<NewMediaItem> newMediaItems) {
    }

    record NewMediaItem(String description, SimpleMediaItem simpleMediaItem) {
    }

    /** {@code uploadToken} is what {@code /v1/uploads} returned, as plain text. */
    record SimpleMediaItem(String uploadToken, String fileName) {
    }

    record BatchCreateResponse(List<NewMediaItemResult> newMediaItemResults) {
    }

    /** A per-item outcome: {@code status.code} 0 means this one was created. */
    record NewMediaItemResult(String uploadToken, Status status, MediaItem mediaItem) {
    }

    record Status(Integer code, String message) {
    }

    /** Google's standard error envelope, which every endpoint here shares. */
    record ApiError(ErrorBody error) {
    }

    record ErrorBody(Integer code, String message, String status) {
    }
}
