// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation

private let kSignInWithGameCenterEndPoint = "signInWithGameCenter"

/// The request to sign in with Game Center account
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
class SignInWithGameCenterRequest: IdentityToolkitRequest, AuthRPCRequest {
  typealias Response = SignInWithGameCenterResponse

  /// The playerID to verify.
  var playerID: String?

  /// The team player ID of the Game Center local player.
  var teamPlayerID: String?

  /// The game player ID of the Game Center local player.
  var gamePlayerID: String?

  /// The URL for the encryption key.
  var publicKeyURL: URL

  /// The verification signature data generated by Game Center.
  var signature: Data

  /// A random strong used to compute the hash and keep it randomized.
  var salt: Data

  /// The date and time that the signature was created.
  var timestamp: UInt64?

  /// The STS Access Token for the authenticated user, only needed for linking the user.
  var accessToken: String?

  /// The display name of the local Game Center player.
  var displayName: String?

  /// Designated initializer.
  /// - Parameter playerID: The ID of the Game Center player.
  /// - Parameter teamPlayerID: The teamPlayerID of the Game Center local player.
  /// - Parameter gamePlayerID: The gamePlayerID of the Game Center local player.
  /// - Parameter publicKeyURL: The URL for the encryption key.
  /// - Parameter signature: The verification signature generated.
  /// - Parameter salt: A random string used to compute the hash and keep it randomized.
  /// - Parameter timestamp: The date and time that the signature was created.
  /// - Parameter displayName: The display name of the Game Center player.
  init(playerID: String?, teamPlayerID: String?, gamePlayerID: String?,
       publicKeyURL: URL,
       signature: Data, salt: Data,
       timestamp: UInt64?, displayName: String?,
       requestConfiguration: AuthRequestConfiguration) {
    self.playerID = playerID
    self.teamPlayerID = teamPlayerID
    self.gamePlayerID = gamePlayerID
    self.publicKeyURL = publicKeyURL
    self.signature = signature
    self.salt = salt
    self.timestamp = timestamp
    self.displayName = displayName
    super.init(
      endpoint: kSignInWithGameCenterEndPoint,
      requestConfiguration: requestConfiguration
    )
  }

  var unencodedHTTPRequestBody: [String: AnyHashable]? {
    var postBody: [String: AnyHashable] = [
      "playerId": playerID,
      "publicKeyUrl": publicKeyURL.absoluteString,
      "signature": signature.base64URLEncodedString(),
      "salt": salt.base64URLEncodedString(),
    ]
    if timestamp != 0 {
      postBody["timestamp"] = timestamp
    }
    if let teamPlayerID {
      postBody["teamPlayerId"] = teamPlayerID
    }
    if let gamePlayerID {
      postBody["gamePlayerId"] = gamePlayerID
    }
    if let accessToken {
      postBody["idToken"] = accessToken
    }
    if let displayName {
      postBody["displayName"] = displayName
    }
    return postBody
  }
}
