package com.google.account;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.FirebaseToken;
import com.google.firebase.auth.SessionCookieOptions;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.CookieParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.concurrent.TimeUnit;

/** Util methods related to firebase auth session cookies. */
public final class FirebaseAuthSessionCookieUtil {
    private static final String ID_TOKEN_PARAM = "idToken";
    private static final String LOG_IN_PAGE_PATH = "/log-in/index.html";

    private FirebaseAuthSessionCookieUtil() {};

    /**
     * Creates the session cookies. It is evoked when the user signs in.
     *
     * @param request Log in request.
     * @return Response with session cookie.
     */
    @POST
    @Path("/business-log-in")
    @Consumes("application/json")
    public static Response createSessionCookie(HttpServletRequest request) {
        try {
            // Gets the ID token sent by the client
            String idToken = getIDToken(request);

            // Sets session expiration to 5 days
            long expiresIn = TimeUnit.DAYS.toMillis(/* duration= */5);
            SessionCookieOptions options = SessionCookieOptions.builder().setExpiresIn(expiresIn).build();

            // Creates the session cookie. This will also verify the ID token in the process.
            // The session cookie will have the same claims as the ID token.
            String sessionCookie = FirebaseAuth.getInstance().createSessionCookieAsync(idToken, options).get();

            // Sets cookie policy parameters as required
            NewCookie cookie = new NewCookie(/* name= */ "session", sessionCookie);
            return Response.ok().cookie(cookie).build();
        } catch (Exception e) {
            return Response.status(Response.Status.UNAUTHORIZED).entity("Failed to create a session cookie").build();
        }
    }

    /**
     * Verifies session cookies.
     *
     * @param cookie Session cookie.
     * @return Response with uid of the current user account.
     */
    @POST
    @Path("/profile")
    public static Response verifySessionCookie(@CookieParam("session") Cookie cookie) {
        String sessionCookie = cookie.getValue();
        try {
            // Verify the session cookie. In this case an additional check is added to detect
            // if the user's Firebase session was revoked, user deleted/disabled, etc.
            final boolean checkRevoked = true;
            FirebaseToken decodedToken = FirebaseAuth.getInstance().verifySessionCookie(sessionCookie, checkRevoked);
            return getUid(decodedToken);
        } catch (FirebaseAuthException e) {
            // Session cookie is unavailable, invalid or revoked. Force user to login.
            return Response.temporaryRedirect(URI.create(LOG_IN_PAGE_PATH)).build();
        }
    }

    /**
     * Clears the session cookie when the user signs out at the client side.
     *
     * @param cookie Session cookie
     * @return Response to direct to log in page.
     */
    @POST
    @Path("/business-log-out")
    public static Response clearSessionCookie(@CookieParam("session") Cookie cookie) {
        final int maxAge = 0;
        NewCookie newCookie = new NewCookie(cookie, /* comment= */ null, maxAge, /* secure= */ true);
        return Response.temporaryRedirect(URI.create(LOG_IN_PAGE_PATH)).cookie(newCookie).build();
    }

    /** Gets the id token from the log in request. */
    private static String getIDToken(HttpServletRequest request) throws IllegalArgumentException {
        String idToken = request.getParameter(ID_TOKEN_PARAM).trim();

        if (idToken == null || idToken.isEmpty()) {
            throw new IllegalArgumentException("ID Token should be an non-empty string");
        }

        return idToken;
    }

    /** Gets the uid the of the current account. */
    private static Response getUid(FirebaseToken decodedToken) {
        String uid = decodedToken.getUid();
        return Response.ok(uid).build();
    }
}

@@ -22,16 +22,149 @@
 count;%0A%0A
+import com.google.auth.oauth2.GoogleCredentials;%0Aimport com.google.firebase.FirebaseApp;%0Aimport com.google.firebase.FirebaseOptions;%0A
 import c
@@ -616,16 +616,44 @@
 sponse;%0A
+import java.io.IOException;%0A
 import j
@@ -956,22 +956,21 @@
 ;%0A%0A    p
-rivate
+ublic
  Firebas
@@ -998,11 +998,58 @@
 l() 
-%7B%7D;
+throws IOException %7B%0A        initAdminSDK();%0A    %7D
 %0A%0A  
@@ -1302,39 +1302,32 @@
 on%22)%0A    public 
-static 
 Response createS
@@ -2553,39 +2553,32 @@
 le%22)%0A    public 
-static 
 Response verifyS
@@ -3859,32 +3859,476 @@
 build();%0A    %7D%0A%0A
+    /** Initializes the admin SDK. */%0A    private void initAdminSDK() throws IOException %7B%0A        FirebaseOptions options = new FirebaseOptions.Builder()%0A                .setCredentials(GoogleCredentials.getApplicationDefault())%0A                .setDatabaseUrl(%22https://com-walk-in-interview.firebaseio.com/%22)%0A                .setProjectId(%22com-walk-in-interview%22)%0A                .build();%0A%0A        FirebaseApp.initializeApp(options);%0A    %7D%0A%0A
     /** Gets the
@@ -4377,23 +4377,16 @@
 private 
-static 
 String g
@@ -4776,23 +4776,16 @@
 private 
-static 
 Response

Initialize admin sdk