/**
   * Adapter for spotify's lookup api
   *
   * @param spotifyId - id of track, has to start with "spotify:track:"
   * @return Track with given id
   * @throws SpotifyApiException - Error contacting spotify,
   * @throws IllegalArgumentException - Is thrown when trying to fetch data that isn't a track
   */
  private SpotifyLookupContainer requestSpotifySong(String spotifyId) throws SpotifyApiException {
    RestTemplate rest = new RestTemplate();
    SpotifyLookupContainer response = null;

    if (spotifyId.indexOf("spotify:track:")
        != 0) { // trying to look up something that isn't a track
      throw new IllegalArgumentException();
    }

    try {
      logger.debug("Fetching spotifysong with uri: " + spotifyId);
      String jsonResponse =
          rest.getForObject("http://ws.spotify.com/lookup/1/.json?uri=" + spotifyId, String.class);
      response =
          gson.fromJson(
              jsonResponse,
              SpotifyLookupContainer
                  .class); // use gson rather than built in spring deserializer which needs the
      // object to match all fields
      if (!isPlayable(response.getTrack())) {
        logger.debug(
            "Song " + response.getTrack().getName() + " is not playable in Norway, ignoring");
        throw new IllegalArgumentException("Song not playable in Norway");
      }

    } catch (RestClientException e) {
      logger.error(
          "Exception while fetching spotifySong " + spotifyId + " error: " + e.getMessage());
      throw new SpotifyApiException(e.getMessage());
    }
    return response;
  }
  public RequestResponse requestSong(String spotifyId, String token, int locationId, String code)
      throws SpotifyApiException, UpdateQRCodeException {

    if (!data.hasSong(spotifyId)) { // Fetch song info from spotify if neccessary
      SpotifyLookupContainer song = requestSpotifySong(spotifyId);
      logger.debug(
          song.getTrack().getName()
              + " - Fetched from spotify, length: "
              + song.getTrack().getLength());
      long length = (long) song.getTrack().getLength() * 1000;
      data.saveSong(
          spotifyId, song.getTrack().getName(), song.getTrack().concatArtistNames(), length);
    }

    int qrValidationCode = qrService.verify(code, locationId);
    if (!data.getSession(locationId).isOpen()) { // session is not open
      return new RequestResponse(
          "Stemming er ikke mulig. Sesjonen er ikke aktiv", false, qrValidationCode);
    } else if (qrValidationCode == QR_IS_NOT_VALID) { // Code is not valid
      return new RequestResponse("QR-koden er ikke gyldig", false, qrValidationCode);
    } else if (qrValidationCode == QR_HAS_UNLIMITED_USES) { // Unlimited votes so check token
      int userId = verifyToken(token); // throws exception if code is not valid or is null

      if (data.userCanRequestSong(spotifyId, locationId, userId)) {
        data.requestSongOneActiveVote(spotifyId, locationId, userId);
      } else {
        logger.debug(
            "User "
                + userId
                + " could not vote for song "
                + spotifyId
                + " at location "
                + locationId);
        return new RequestResponse(
            "Denne brukeren har allerede stemt opp denne sangen", false, qrValidationCode);
      }
    } else if (qrValidationCode == QR_HAS_LIMITED_USES) { // Limited votes, so token not neccessary
      int userId = authService.verify(token);
      if (userId == -1) { // Token null or not valid
        userId = -1337; // The fake spotify user
      }
      boolean success =
          data.requestSongManyActiveVotes(
              spotifyId,
              locationId,
              userId); // No need to update qrcodes and such.//Jo? Have to decrement the uses.
      if (success) {
        if (!qrService.codeIsUsed(code)) {
          logger.debug("Could not update QRcode");
        }
      } else {
        return new RequestResponse("Kunne ikke oppdatere databasen", false, qrValidationCode);
      }
    }

    return new RequestResponse("Stemmen ble registrert", true, qrValidationCode);
  }