/*
 * Copyright (c) 2015 Eike Stepper (Berlin, Germany) and others.
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.userstorage.tests.util;

import org.eclipse.userstorage.internal.util.IOUtil;
import org.eclipse.userstorage.internal.util.JSONUtil;
import org.eclipse.userstorage.internal.util.StringUtil;
import org.eclipse.userstorage.spi.Credentials;
import org.eclipse.userstorage.tests.StorageTests;

import org.eclipse.core.runtime.Path;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * @author Eike Stepper
 */
public final class USSServer
{
  public static final String BLOB_EXTENSION = ".blob";

  public static final String ETAG_EXTENSION = ".etag";

  private static final boolean DEBUG = Boolean.getBoolean("org.eclipse.userstorage.tests.server.debug");

  private final USSHandler handler = new USSHandler();

  private final Set<String> applicationTokens = new HashSet<String>();

  private final Map<String, User> users = new HashMap<String, User>();

  private final Map<String, Session> sessions = new HashMap<String, Session>();

  private final File folder;

  private final int startPort;

  private int port;

  private Server server;

  public USSServer(int startPort, File folder)
  {
    this.startPort = startPort;
    this.folder = folder;
  }

  public int getPort()
  {
    return port;
  }

  public File getFolder()
  {
    return folder;
  }

  public Set<String> getApplicationTokens()
  {
    return applicationTokens;
  }

  public Map<String, User> getUsers()
  {
    return users;
  }

  public User addUser(Credentials credentials)
  {
    return addUser(credentials.getUsername(), credentials.getPassword());
  }

  public User addUser(String username, String password)
  {
    User user = new User(username, password);
    users.put(user.getUsername(), user);
    return user;
  }

  public File getUserFile(User user, String applicationToken, String key, String extension)
  {
    return new File(getApplicationFolder(user, applicationToken), key + StringUtil.safe(extension));
  }

  public File getApplicationFolder(User user, String applicationToken)
  {
    return new File(new File(folder, user.getUsername()), applicationToken);
  }

  public Map<String, Session> getSessions()
  {
    return sessions;
  }

  public int start() throws Exception
  {
    Exception exception = new Exception("No free port");

    for (port = startPort; port < 65535; port++)
    {
      server = new Server(port);
      server.setHandler(handler);

      try
      {
        server.start();
        return port;
      }
      catch (Exception ex)
      {
        exception = ex;

        try
        {
          server.stop();
        }
        catch (Exception ignore)
        {
          //$FALL-THROUGH$
        }
        finally
        {
          server = null;
        }
      }
    }

    throw exception;
  }

  public void stop() throws Exception
  {
    if (server != null)
    {
      server.stop();
      server = null;
    }
  }

  public void join() throws InterruptedException
  {
    if (server != null)
    {
      server.join();
    }
  }

  protected void login(HttpServletRequest request, HttpServletResponse response) throws IOException
  {
    Map<String, Object> requestObject = JSONUtil.parse(request.getInputStream(), null);

    String username = (String)requestObject.get("username");
    String password = (String)requestObject.get("password");

    User user = users.get(username);
    if (user == null || password == null || !password.equals(user.getPassword()))
    {
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
      return;
    }

    response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/json");

    Session session = addSession(user);
    Cookie cookie = new Cookie("SESSION", session.getID());
    cookie.setPath("/");
    response.addCookie(cookie);

    Map<String, Object> responseObject = new LinkedHashMap<String, Object>();
    responseObject.put("sessid", session.getID());
    responseObject.put("token", session.getCSRFToken());
    InputStream body = JSONUtil.build(responseObject);

    try
    {
      ServletOutputStream out = response.getOutputStream();
      IOUtil.copy(body, out);
      out.flush();
    }
    finally
    {
      IOUtil.closeSilent(body);
    }
  }

  protected void retrieveProperties(HttpServletRequest request, HttpServletResponse response, File applicationFolder) throws IOException
  {
    String applicationToken = applicationFolder.getName();

    int pageSize = getIntParameter(request, "pageSize", 20);
    if (pageSize < 1 || pageSize > 100)
    {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid page size");
      return;
    }

    int page = getIntParameter(request, "page", 20);
    if (page < 1)
    {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid page");
      return;
    }

    boolean empty = true;

    StringBuilder builder = new StringBuilder();
    builder.append('[');

    File[] files = applicationFolder.listFiles();
    if (files != null)
    {
      int first = (page - 1) * pageSize + 1;
      System.out.println("##### " + first);
      int i = 0;

      for (File file : files)
      {
        String name = file.getName();
        if (name.endsWith(ETAG_EXTENSION))
        {
          if (++i >= first)
          {
            String key = name.substring(0, name.length() - ETAG_EXTENSION.length());
            System.out.println("##### " + key);
            String etag = IOUtil.readUTF(file);

            if (empty)
            {
              empty = false;
            }
            else
            {
              builder.append(",");
            }

            builder.append("{\"application_token\":\"");
            builder.append(applicationToken);
            builder.append("\",\"key\":\"");
            builder.append(key);
            builder.append("\",\"etag\":\"");
            builder.append(etag);
            builder.append("\"}");

            if (--pageSize == 0)
            {
              break;
            }
          }
        }
      }
    }

    builder.append(']');
    System.out.println(builder);

    response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/json");

    InputStream body = IOUtil.streamUTF(builder.toString());

    try
    {
      ServletOutputStream out = response.getOutputStream();
      IOUtil.copy(body, out);
      out.flush();
    }
    finally
    {
      IOUtil.closeSilent(body);
    }
  }

  protected void retrieveBlob(HttpServletRequest request, HttpServletResponse response, File blobFile, File etagFile, boolean exists) throws IOException
  {
    if (!exists)
    {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    String etag = IOUtil.readUTF(etagFile);
    String ifNoneMatch = getETag(request, "If-None-Match");
    if (ifNoneMatch != null && ifNoneMatch.equals(etag))
    {
      response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
      return;
    }

    response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/json");
    response.setHeader("ETag", "\"" + etag + "\"");

    InputStream body = JSONUtil.build(Collections.singletonMap("value", new FileInputStream(blobFile)));

    try
    {
      ServletOutputStream out = response.getOutputStream();
      IOUtil.copy(body, out);
      out.flush();
    }
    finally
    {
      IOUtil.closeSilent(body);
    }
  }

  protected void updateBlob(HttpServletRequest request, HttpServletResponse response, File blobFile, File etagFile, boolean exists) throws IOException
  {
    String ifMatch = getETag(request, "If-Match");

    if (exists)
    {
      String etag = IOUtil.readUTF(etagFile);

      if (StringUtil.isEmpty(ifMatch) || !ifMatch.equals(etag))
      {
        response.setHeader("ETag", "\"" + etag + "\"");
        response.setStatus(HttpServletResponse.SC_CONFLICT);
        return;
      }
    }

    String etag = UUID.randomUUID().toString();

    IOUtil.mkdirs(blobFile.getParentFile());
    FileOutputStream out = new FileOutputStream(blobFile);
    InputStream body = null;

    try
    {
      Map<String, Object> requestObject = JSONUtil.parse(request.getInputStream(), "value");
      body = (InputStream)requestObject.get("value");

      IOUtil.copy(body, out);
    }
    finally
    {
      IOUtil.closeSilent(body);
      IOUtil.close(out);
    }

    IOUtil.writeUTF(etagFile, etag);

    response.setStatus(exists ? HttpServletResponse.SC_OK : HttpServletResponse.SC_CREATED);
    response.setHeader("ETag", "\"" + etag + "\"");
  }

  protected void deleteBlob(HttpServletRequest request, HttpServletResponse response, File blobFile, File etagFile, boolean exists) throws IOException
  {
    if (exists)
    {
      String etag = IOUtil.readUTF(etagFile);
      String ifMatch = getETag(request, "If-Match");
      if (ifMatch != null && !ifMatch.equals(etag))
      {
        response.sendError(HttpServletResponse.SC_CONFLICT);
        return;
      }
    }
    else
    {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    IOUtil.delete(blobFile);
    IOUtil.delete(etagFile);

    response.setStatus(HttpServletResponse.SC_NO_CONTENT);
  }

  private Session getSession(HttpServletRequest request)
  {
    String csrfToken = request.getHeader("X-CSRF-Token");
    if (csrfToken != null)
    {
      Cookie[] cookies = request.getCookies();
      if (cookies != null)
      {
        for (Cookie cookie : cookies)
        {
          if ("SESSION".equals(cookie.getName()))
          {
            String sessionID = cookie.getValue();
            Session session = sessions.get(sessionID);

            if (session != null && session.getCSRFToken().equals(csrfToken))
            {
              return session;
            }

            break;
          }
        }
      }
    }

    return null;
  }

  private Session addSession(User user)
  {
    Session session = new Session(user);
    sessions.put(session.getID(), session);
    return session;
  }

  private static String getETag(HttpServletRequest request, String headerName)
  {
    String eTag = request.getHeader(headerName);
    if (eTag != null)
    {
      // Remove the quotes.
      eTag = eTag.substring(1, eTag.length() - 1);
    }

    return eTag;
  }

  @SuppressWarnings("restriction")
  private static String getReasonPhrase(int status)
  {
    try
    {
      return org.apache.http.impl.EnglishReasonPhraseCatalog.INSTANCE.getReason(status, null);
    }
    catch (Throwable ex)
    {
      return "";
    }
  }

  private static int getIntParameter(HttpServletRequest request, String name, int defaultValue)
  {
    String parameter = request.getParameter(name);
    if (parameter != null)
    {
      try
      {
        return Integer.parseInt(parameter);
      }
      catch (NumberFormatException ex)
      {
        //$FALL-THROUGH$
      }
    }

    return defaultValue;
  }

  /**
   * @author Eike Stepper
   */
  private class USSHandler extends AbstractHandler
  {
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
      try
      {
        baseRequest.setHandled(true);

        String userAgent = request.getHeader("User-Agent");
        if (!org.eclipse.userstorage.internal.Session.USER_AGENT_ID.equals(userAgent))
        {
          response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid User-Agent");
          return;
        }

        String method = request.getMethod();
        String path = request.getPathInfo();

        if (DEBUG)
        {
          StringBuilder builder = new StringBuilder();
          builder.append(method);
          builder.append(" ");
          builder.append(path);
          builder.append('\n');

          Enumeration<String> headerNames = request.getHeaderNames();
          while (headerNames.hasMoreElements())
          {
            String headerName = headerNames.nextElement();
            Enumeration<String> headers = request.getHeaders(headerName);
            while (headers.hasMoreElements())
            {
              String header = headers.nextElement();
              builder.append("   ");
              builder.append(headerName);
              builder.append(": ");
              builder.append(header);
              builder.append('\n');
            }
          }

          System.out.print(builder);
          System.out.flush();
        }

        if (path != null && method != null)
        {
          handle(method, path, request, response);

          if (DEBUG)
          {
            int status = response.getStatus();
            String reasonPhrase = getReasonPhrase(status);

            StringBuilder builder = new StringBuilder();
            builder.append(request.getProtocol());
            builder.append(" ");
            builder.append(status);
            if (!StringUtil.isEmpty(reasonPhrase))
            {
              builder.append(" ");
              builder.append(reasonPhrase);
            }

            builder.append('\n');

            for (String headerName : response.getHeaderNames())
            {
              for (String header : response.getHeaders(headerName))
              {
                builder.append("   ");
                builder.append(headerName);
                builder.append(": ");
                builder.append(header);
                builder.append('\n');
              }
            }

            System.out.println(builder);
          }
        }
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
        throw ex;
      }
      catch (RuntimeException ex)
      {
        ex.printStackTrace();
        throw ex;
      }
    }

    private void handle(String method, String path, HttpServletRequest request, HttpServletResponse response) throws IOException
    {
      if (path.equals("/api/user/login") && HttpMethod.POST.is(method))
      {
        login(request, response);
        return;
      }

      Session session = getSession(request);
      if (session == null)
      {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return;
      }

      if (path.startsWith("/api/blob"))
      {
        User user = session.getUser();
        Path segments = new Path(path);

        String applicationToken = segments.segment(2);
        if (!applicationTokens.contains(applicationToken))
        {
          response.sendError(HttpServletResponse.SC_NOT_FOUND);
          return;
        }

        if (segments.segmentCount() < 4)
        {
          if (HttpMethod.GET.is(method))
          {
            File applicationFolder = getApplicationFolder(user, applicationToken);
            retrieveProperties(request, response, applicationFolder);
            return;
          }

          response.sendError(HttpServletResponse.SC_FORBIDDEN);
          return;
        }

        String key = segments.segment(3);
        File blobFile = getUserFile(user, applicationToken, key, BLOB_EXTENSION);
        File etagFile = getUserFile(user, applicationToken, key, ETAG_EXTENSION);
        boolean exists = etagFile.exists();

        if (HttpMethod.GET.is(method))
        {
          retrieveBlob(request, response, blobFile, etagFile, exists);
          return;
        }

        if (HttpMethod.PUT.is(method))
        {
          updateBlob(request, response, blobFile, etagFile, exists);
          return;
        }

        if (HttpMethod.DELETE.is(method))
        {
          deleteBlob(request, response, blobFile, etagFile, exists);
          return;
        }

        return;
      }

      response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
  }

  /**
  * @author Eike Stepper
  */
  public static final class User
  {
    private final String username;

    private final byte[] password;

    public User(String username, String password)
    {
      this.username = username;
      this.password = StringUtil.encrypt(password);
    }

    public String getUsername()
    {
      return username;
    }

    public String getPassword()
    {
      return StringUtil.decrypt(password);
    }

    @Override
    public String toString()
    {
      return username;
    }

    @Override
    public int hashCode()
    {
      return username.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
      if (this == obj)
      {
        return true;
      }

      if (obj == null)
      {
        return false;
      }

      if (getClass() != obj.getClass())
      {
        return false;
      }

      User other = (User)obj;
      if (username == null)
      {
        if (other.username != null)
        {
          return false;
        }
      }
      else if (!username.equals(other.username))
      {
        return false;
      }

      return true;
    }
  }

  /**
  * @author Eike Stepper
  */
  public static final class Session
  {
    private final String id;

    private final String csrfToken;

    private final User user;

    public Session(User user)
    {
      id = UUID.randomUUID().toString();
      csrfToken = UUID.randomUUID().toString();
      this.user = user;
    }

    public String getID()
    {
      return id;
    }

    public String getCSRFToken()
    {
      return csrfToken;
    }

    public User getUser()
    {
      return user;
    }

    @Override
    public int hashCode()
    {
      return id.hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
      if (this == obj)
      {
        return true;
      }

      if (obj == null)
      {
        return false;
      }

      if (getClass() != obj.getClass())
      {
        return false;
      }

      Session other = (Session)obj;
      if (id == null)
      {
        if (other.id != null)
        {
          return false;
        }
      }
      else if (!id.equals(other.id))
      {
        return false;
      }

      return true;
    }

    @Override
    public String toString()
    {
      return id + " -> " + user;
    }
  }

  public static void main(String[] args) throws Exception
  {
    USSServer server = new USSServer(8080, new File(System.getProperty("java.io.tmpdir"), "uss-server"));
    server.addUser(FixedCredentialsProvider.DEFAULT_CREDENTIALS);

    Set<String> applicationTokens = server.getApplicationTokens();
    applicationTokens.add(StorageTests.APPLICATION_TOKEN);
    applicationTokens.add("cNhDr0INs8T109P8h6E1r_GvU3I"); // Oomph

    System.out.println(server.getFolder());
    System.out.println("Listening on port " + server.start());
    server.join();
  }
}
