// Path: library/src/main/java/com/pokegoapi/util/hash/Hash.java
// public class Hash {
// 	@Getter
// 	public final int locationAuthHash;
// 	@Getter
// 	public final int locationHash;
// 	@Getter
// 	public final List<Long> requestHashes;
// 
// 	/**
// 	 * Creates a hash object
// 	 *
// 	 * @param locationAuthHash the hash of the location and auth ticket
// 	 * @param locationHash the hash of the location
// 	 * @param requestHashes the hash of each request
// 	 */
// 	public Hash(int locationAuthHash, int locationHash, List<Long> requestHashes) {
// 		this.locationAuthHash = locationAuthHash;
// 		this.locationHash = locationHash;
// 		this.requestHashes = requestHashes;
// 	}
// }


import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import com.pokegoapi.exceptions.request.HashException;
import com.pokegoapi.exceptions.request.HashLimitExceededException;
import com.pokegoapi.exceptions.request.HashUnauthorizedException;
import com.pokegoapi.util.hash.Hash;
import com.pokegoapi.util.hash.HashProvider;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Moshi.Builder;
import lombok.Getter;
import lombok.Setter;
import net.iharder.Base64;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/*
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.pokegoapi.util.hash.pokehash;



/**
 * Hash provider on latest version, using the PokeHash hashing service.
 * This requires a key and is not free like the legacy provider.
 * @see <a href="https://hashing.pogodev.org/">https://hashing.pogodev.org/</a>
 */
public class PokeHashProvider implements HashProvider {
	private static final String DEFAULT_ENDPOINT = "https://pokehash.buddyauth.com/api/v159_1/hash";

	@Getter
	@Setter
	private String endpoint = DEFAULT_ENDPOINT;

	private static final int VERSION = 9100;
	private static final long UNK25 = -782790124105039914L;

	private static final Moshi MOSHI = new Builder().build();

	@Getter
	private final PokeHashKey key;
	@Getter
	private final boolean awaitRequests;

	/**
	 * Creates a PokeHashProvider with the given key
	 *
	 * @param key the key for the PokeHash API
	 * @param awaitRequest true if the API should, when the rate limit has been exceeded, wait until the current
	 *     period ends, or false to throw a HashLimitExceededException
	 */
	public PokeHashProvider(PokeHashKey key, boolean awaitRequest) {
		this.key = key;
		this.awaitRequests = awaitRequest;
		if (key == null || key.key == null) {
			throw new IllegalArgumentException("Key cannot be null!");
		}
	}

	/**
	 * Provides a hash for the given arguments
	 *
	 * @param timestamp timestamp to hash
	 * @param latitude latitude to hash
	 * @param longitude longitude to hash
	 * @param altitude altitude to hash
	 * @param authTicket auth ticket to hash
	 * @param sessionData session data to hash
	 * @param requests request data to hash
	 * @return the hash provider
	 * @throws HashException if an exception occurs while providing this hash
	 */
	@Override
// Path: library/src/main/java/com/pokegoapi/util/hash/Hash.java
// public class Hash {
// 	@Getter
// 	public final int locationAuthHash;
// 	@Getter
// 	public final int locationHash;
// 	@Getter
// 	public final List<Long> requestHashes;
// 
// 	/**
// 	 * Creates a hash object
// 	 *
// 	 * @param locationAuthHash the hash of the location and auth ticket
// 	 * @param locationHash the hash of the location
// 	 * @param requestHashes the hash of each request
// 	 */
// 	public Hash(int locationAuthHash, int locationHash, List<Long> requestHashes) {
// 		this.locationAuthHash = locationAuthHash;
// 		this.locationHash = locationHash;
// 		this.requestHashes = requestHashes;
// 	}
// }


// Path: library/src/main/java/com/pokegoapi/util/hash/pokehash/PokeHashProvider.java
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import com.pokegoapi.exceptions.request.HashException;
import com.pokegoapi.exceptions.request.HashLimitExceededException;
import com.pokegoapi.exceptions.request.HashUnauthorizedException;
import com.pokegoapi.util.hash.Hash;
import com.pokegoapi.util.hash.HashProvider;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Moshi.Builder;
import lombok.Getter;
import lombok.Setter;
import net.iharder.Base64;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/*
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.pokegoapi.util.hash.pokehash;



/**
 * Hash provider on latest version, using the PokeHash hashing service.
 * This requires a key and is not free like the legacy provider.
 * @see <a href="https://hashing.pogodev.org/">https://hashing.pogodev.org/</a>
 */
public class PokeHashProvider implements HashProvider {
	private static final String DEFAULT_ENDPOINT = "https://pokehash.buddyauth.com/api/v159_1/hash";

	@Getter
	@Setter
	private String endpoint = DEFAULT_ENDPOINT;

	private static final int VERSION = 9100;
	private static final long UNK25 = -782790124105039914L;

	private static final Moshi MOSHI = new Builder().build();

	@Getter
	private final PokeHashKey key;
	@Getter
	private final boolean awaitRequests;

	/**
	 * Creates a PokeHashProvider with the given key
	 *
	 * @param key the key for the PokeHash API
	 * @param awaitRequest true if the API should, when the rate limit has been exceeded, wait until the current
	 *     period ends, or false to throw a HashLimitExceededException
	 */
	public PokeHashProvider(PokeHashKey key, boolean awaitRequest) {
		this.key = key;
		this.awaitRequests = awaitRequest;
		if (key == null || key.key == null) {
			throw new IllegalArgumentException("Key cannot be null!");
		}
	}

	/**
	 * Provides a hash for the given arguments
	 *
	 * @param timestamp timestamp to hash
	 * @param latitude latitude to hash
	 * @param longitude longitude to hash
	 * @param altitude altitude to hash
	 * @param authTicket auth ticket to hash
	 * @param sessionData session data to hash
	 * @param requests request data to hash
	 * @return the hash provider
	 * @throws HashException if an exception occurs while providing this hash
	 */
	@Override
	public Hash provide(long timestamp, double latitude, double longitude, double altitude, byte[] authTicket,