// Copyright (C) 2013 The Android Open Source Project
//
// 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
//
// http://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.googlesource.gerrit.plugins.github.oauth;


import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.kohsuke.github.GHMyself;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.util.Random;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Singleton
public class OAuthWebFilter implements Filter {
  private static final org.slf4j.Logger log = LoggerFactory
      .getLogger(OAuthWebFilter.class);
  public static final String GERRIT_COOKIE_NAME = "GerritAccount";
  public static final String GITHUB_EXT_ID = "github_oauth:";

  private final GitHubOAuthConfig config;
  private final Random retryRandom = new Random(System.currentTimeMillis());
  private final SitePaths sites;
  private final ScopedProvider<GitHubLogin> loginProvider;
  private final OAuthProtocol oauth;

  @Inject
  public OAuthWebFilter(GitHubOAuthConfig config, 
      SitePaths sites,
      OAuthProtocol oauth,
  // We need to explicitly tell Guice the correct implementation
  // as this filter is instantiated with a standard Gerrit WebModule
      GitHubLogin.Provider loginProvider) {
    this.config = config;
    this.sites = sites;
    this.oauth = oauth;
    this.loginProvider = loginProvider;
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    log.debug("OAuthWebFilter(" + httpRequest.getRequestURL() + ") code="
        + request.getParameter("code"));

    Cookie gerritCookie = getGerritCookie(httpRequest);
    try {
      GitHubLogin ghLogin = loginProvider.get(httpRequest);

      if (OAuthProtocol.isOAuthRequest(httpRequest)) {
        login(request, httpRequest, httpResponse, ghLogin);
      } else {
        if (OAuthProtocol.isOAuthLogout(httpRequest)) {
          httpResponse =
              (HttpServletResponse) logout(request, httpResponse, chain, httpRequest);
        }

        if (ghLogin != null && ghLogin.isLoggedIn()) {
          httpRequest =
              new AuthenticatedHttpRequest(httpRequest, config.httpHeader,
                  ghLogin.getMyself().getLogin(), config.oauthHttpHeader,
                  GITHUB_EXT_ID + ghLogin.getToken().accessToken);
        }

        chain.doFilter(httpRequest, httpResponse);
      }
    } finally {
      HttpSession httpSession = httpRequest.getSession();
      if (gerritCookie != null && httpSession != null) {
        String gerritCookieValue = gerritCookie.getValue();
        String gerritSessionValue =
            (String) httpSession.getAttribute("GerritAccount");

        if (gerritSessionValue == null) {
          httpSession.setAttribute("GerritAccount", gerritCookieValue);
        } else if (!gerritSessionValue.equals(gerritCookieValue)) {
          httpSession.invalidate();
        }
      }
    }
  }

  private void login(ServletRequest request, HttpServletRequest httpRequest,
      HttpServletResponse httpResponse, GitHubLogin ghLogin) throws IOException {
    ghLogin.login(httpRequest, httpResponse, oauth);
    if (ghLogin.isLoggedIn()) {
      GHMyself myself = ghLogin.getMyself();
      String user = myself.getLogin();

      updateSecureConfigWithRetry(ghLogin.getHub().getMyOrganizations().keySet(),
          user, ghLogin.getToken().accessToken);
    }
  }

  private ServletResponse logout(ServletRequest request,
      ServletResponse response, FilterChain chain,
      HttpServletRequest httpRequest) {
    getGitHubLogin(request).logout();
    return new GitHubLogoutServletResponse((HttpServletResponse) response,
        config.logoutRedirectUrl);
  }

  private GitHubLogin getGitHubLogin(ServletRequest request) {
    return loginProvider.get((HttpServletRequest) request);
  }

  private void updateSecureConfigWithRetry(Set<String> organisations,
      String user, String access_token) {
    int retryCount = 0;

    while (retryCount < config.fileUpdateMaxRetryCount) {
      try {
        updateSecureConfig(organisations, user, access_token);
        return;
      } catch (IOException e) {
        retryCount++;
        int retryInterval =
            retryRandom.nextInt(config.fileUpdateMaxRetryIntervalMsec);
        log.warn("Error whilst trying to update "
            + sites.secure_config
            + (retryCount < config.fileUpdateMaxRetryCount ? ": attempt #"
                + retryCount + " will be retried after " + retryInterval
                + " msecs" : ""), e);
        try {
          Thread.sleep(retryInterval);
        } catch (InterruptedException e1) {
          log.error("Thread has been cancelled before retrying to save "
              + sites.secure_config);
          return;
        }
      } catch (ConfigInvalidException e) {
        log.error("Cannot update " + sites.secure_config
            + " as the file is corrupted", e);
        return;
      }
    }
  }

  private synchronized void updateSecureConfig(Set<String> organisations,
      String user, String access_token) throws IOException,
      ConfigInvalidException {
    FileBasedConfig currentSecureConfig =
        new FileBasedConfig(sites.secure_config.toFile(), FS.DETECTED);
    FileTime currentSecureConfigUpdateTs = Files.getLastModifiedTime(sites.secure_config);
    currentSecureConfig.load();

    boolean configUpdate =
        updateConfigSection(currentSecureConfig, user, user, access_token);
    for (String organisation : organisations) {
      configUpdate |=
          updateConfigSection(currentSecureConfig, organisation, user,
              access_token);
    }

    if (!configUpdate) {
      return;
    }

    log.info("Updating " + sites.secure_config + " credentials for user "
        + user);

    FileTime secureConfigCurrentModifiedTime =
        Files.getLastModifiedTime(sites.secure_config);
    if (!secureConfigCurrentModifiedTime.equals(currentSecureConfigUpdateTs)) {
      throw new ConcurrentFileBasedConfigWriteException("File "
          + sites.secure_config + " was written at "
          + secureConfigCurrentModifiedTime
          + " while was trying to update security for user " + user);
    }
    currentSecureConfig.save();
  }

  private boolean updateConfigSection(FileBasedConfig c, String section,
      String user, String password) {
    String configUser = c.getString("remote", section, "username");
    String configPassword = c.getString("remote", section, "password");
    if (!StringUtils.equals(configUser, user)
        || StringUtils.equals(configPassword, password)) {
      return false;
    }

    c.setString("remote", section, "username", user);
    c.setString("remote", section, "password", password);
    return true;
  }

  private Cookie getGerritCookie(HttpServletRequest httpRequest) {
    for (Cookie cookie : getCookies(httpRequest)) {
      if (cookie.getName().equalsIgnoreCase(GERRIT_COOKIE_NAME)) {
        return cookie;
      }
    }
    return null;
  }

  private Cookie[] getCookies(HttpServletRequest httpRequest) {
    Cookie[] cookies = httpRequest.getCookies();
    return cookies == null ? new Cookie[0] : cookies;
  }

  @Override
  public void destroy() {
    log.info("Init");
  }
}
