package com.airlock.iam.oauth2.domain.model.session;

import com.airlock.iam.oauth2.api.domain.model.OAuth2ClientId;
import com.airlock.iam.oauth2.domain.model.WebOrigin;
import com.airlock.iam.security.util.crypto.random.AlphanumericRandomStringGenerator;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.digests.SHA256Digest;

public class OpenIdConnectSessionStateCalculator {
   private final Optional<OpenIDProviderUserAgentState> opuas;

   public Optional<String> sessionState(String redirectUri, OAuth2ClientId clientId) {
      if (this.opuas.isEmpty()) {
         return Optional.empty();
      }

      String salt = AlphanumericRandomStringGenerator.generateAlphanumericRandomString(20);
      return Optional.of(
         sha256Hex(clientId.id() + " " + WebOrigin.webOrigin(URI.create(redirectUri)).getOrigin() + " " + this.opuas.get().getState() + " " + salt)
            + "."
            + salt
      );
   }

   private static String sha256Hex(String str) {
      SHA256Digest sha256 = new SHA256Digest();
      sha256.update(str.getBytes(StandardCharsets.US_ASCII), 0, str.length());
      byte[] sha256Hash = new byte[sha256.getDigestSize()];
      sha256.doFinal(sha256Hash, 0);
      return Hex.encodeHexString(sha256Hash);
   }

   @SuppressFBWarnings(justification = "generated code")
   public OpenIdConnectSessionStateCalculator(Optional<OpenIDProviderUserAgentState> opuas) {
      this.opuas = opuas;
   }
}
