// Copyright 2021 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
//
//     https://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.

package com.google.sps.servlets;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.FirebaseToken;
import com.google.gson.Gson;
import com.google.sps.data.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

@WebServlet("/authentication")
public class AuthServlet extends HttpServlet {
  private static final Logger LOGGER = Logger.getLogger(AuthServlet.class.getName());

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    DataSource pool = (DataSource) request.getServletContext().getAttribute("db-connection-pool");

    try (Connection conn = pool.getConnection()) {
      String email = request.getParameter("email");
      String name = request.getParameter("name");
      LOGGER.log(Level.WARNING, name);
      LOGGER.log(Level.WARNING, email);
      User user = getUser(conn, email);

      if (user == null) {
        // the user is not already in the database - create a new one
        user = addUser(conn, name, email);
      }

      Gson gson = new Gson();
      response.setContentType("application/json");
      response.getWriter().println(gson.toJson(user));
      // response.setContentType("text/html;");
      // response.getWriter().println("<h1>" + user + "</h1>");
    } catch (SQLException ex) {
      LOGGER.log(Level.WARNING, "Error while attempting to find user.", ex);
      response.setStatus(500);
      response.getWriter().write("Unable to successfully fetch user");
    }
  }

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String uid = verifyIDToken(request);
    //stored the user data in the session
    request.getSession().setAttribute("uid",uid);
  }

  @Override
  public void doDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.getSession().setAttribute("uid",null);
  }

  /**
   *  Get the ID Token that is passed though request, verify the user and return the decoded uid.
   * @param request -- request
   * @return decoded ID Token.
   * @throws IOException
   */
  private String verifyIDToken(HttpServletRequest request) throws IOException{
    //get the client ID Token from the request body
    StringBuilder buffer = new StringBuilder();
    BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
      buffer.append(line);
      buffer.append(System.lineSeparator());
    }
    String body = buffer.toString();

    //decode and verify client ID token
    FirebaseToken decodedToken = null;
    try {
      decodedToken = FirebaseAuth.getInstance().verifyIdToken(body);
    } catch (FirebaseAuthException e) {
      e.printStackTrace();
    }

    return decodedToken.getUid();
  }

  private User getUser(Connection conn, String email) throws SQLException {
    String stmt = "SELECT id, name FROM users WHERE email='" + email + "';";
    try (PreparedStatement userStmt = conn.prepareStatement(stmt);) {
      // Execute the statement
      ResultSet rs = userStmt.executeQuery();
      // Convert a result into User object
      int id;
      String name;
      User user;
      while (rs.next()) {
        id = rs.getInt(1);
        name = rs.getString(2);
        return User.create(id, name, email);
      }
      return null;
    }
  }

  private User addUser(Connection conn, String name, String email) throws SQLException {
    String stmt = "INSERT INTO users (name, email) VALUES ('" + name + "', '" + email + "');";
    try (PreparedStatement userStmt = conn.prepareStatement(stmt);) {
      // Execute the statement
      userStmt.execute();
      LOGGER.log(Level.INFO, "User " + name + " added to database.");

    }
    String getId = "SELECT LAST_INSERT_ID();";
    try (PreparedStatement idStmt = conn.prepareStatement(getId);) {
      ResultSet rs = idStmt.executeQuery();
      int id;
      while (rs.next()) {
        id = rs.getInt(1);
        return User.create(id, name, email);
      }
      return null;
    }
  }
}
@@ -627,295 +627,266 @@
 ort 
-com.google.firebase.auth.FirebaseAuth;%0Aimport com.google.firebase.auth.FirebaseAuthException;%0Aimport com.google.firebase.auth.FirebaseToken;%0Aimport com.google.gson.Gson;%0Aimport com.google.sps.data.*;%0A%0Aimport java.io.BufferedReader;%0Aimport java.io.IOException;%0Aimport java.sql.Connection;
+java.io.IOException;%0Aimport javax.servlet.annotation.WebServlet;%0Aimport javax.servlet.http.HttpServlet;%0Aimport javax.servlet.http.HttpServletRequest;%0Aimport javax.servlet.http.HttpServletResponse;%0Aimport com.google.gson.Gson;%0Aimport com.google.sps.data.*;  %0A
 %0Aimp
@@ -940,24 +940,52 @@
 .ResultSet;%0A
+import java.sql.Connection;%0A
 import java.
@@ -994,32 +994,62 @@
 l.SQLException;%0A
+import javax.sql.DataSource;%0A%0A
 import java.util
@@ -1100,213 +1100,8 @@
 ger;
-%0Aimport javax.servlet.annotation.WebServlet;%0Aimport javax.servlet.http.HttpServlet;%0Aimport javax.servlet.http.HttpServletRequest;%0Aimport javax.servlet.http.HttpServletResponse;%0Aimport javax.sql.DataSource;
 %0A%0A@W
@@ -1176,16 +1176,17 @@
 rvlet %7B%0A
+%0A
   privat
@@ -1632,87 +1632,8 @@
 %22);%0A
-      LOGGER.log(Level.WARNING, name);%0A      LOGGER.log(Level.WARNING, email);%0A
     
@@ -1953,33 +1953,32 @@
 user));%0A      //
- 
 response.setCont
@@ -2008,17 +2008,16 @@
       //
- 
 response
@@ -2289,1306 +2289,8 @@
  %7D%0A%0A
-  @Override%0A  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException %7B%0A    String uid = verifyIDToken(request);%0A    //stored the user data in the session%0A    request.getSession().setAttribute(%22uid%22,uid);%0A  %7D%0A%0A  @Override%0A  public void doDelete(HttpServletRequest request, HttpServletResponse response) throws IOException %7B%0A    request.getSession().setAttribute(%22uid%22,null);%0A  %7D%0A%0A  /**%0A   *  Get the ID Token that is passed though request, verify the user and return the decoded uid.%0A   * @param request -- request%0A   * @return decoded ID Token.%0A   * @throws IOException%0A   */%0A  private String verifyIDToken(HttpServletRequest request) throws IOException%7B%0A    //get the client ID Token from the request body%0A    StringBuilder buffer = new StringBuilder();%0A    BufferedReader reader = request.getReader();%0A    String line;%0A    while ((line = reader.readLine()) != null) %7B%0A      buffer.append(line);%0A      buffer.append(System.lineSeparator());%0A    %7D%0A    String body = buffer.toString();%0A%0A    //decode and verify client ID token%0A    FirebaseToken decodedToken = null;%0A    try %7B%0A      decodedToken = FirebaseAuth.getInstance().verifyIdToken(body);%0A    %7D catch (FirebaseAuthException e) %7B%0A      e.printStackTrace();%0A    %7D%0A%0A    return decodedToken.getUid();%0A  %7D%0A%0A
   pr
@@ -3008,16 +3008,17 @@
 ame + %22'
+'
 , '%22 + e
@@ -3026,16 +3026,17 @@
 ail + %22'
+'
 );%22;%0A   

Remove unnecessary logs