// 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.wizard;

import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.entities.Account.Id;
import com.google.gerrit.extensions.api.accounts.SshKeyInput;
import com.google.gerrit.extensions.common.NameInput;
import com.google.gerrit.extensions.common.SshKeyInfo;
import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.account.AuthResult;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.restapi.account.AddSshKey;
import com.google.gerrit.server.restapi.account.GetSshKeys;
import com.google.gerrit.server.restapi.account.PutName;
import com.google.gerrit.server.restapi.account.PutPreferred;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.github.oauth.GitHubLogin;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.kohsuke.github.GHKey;
import org.kohsuke.github.GHMyself;
import org.kohsuke.github.GHVerifiedKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AccountController implements VelocityController {

  private static final Logger log = LoggerFactory.getLogger(AccountController.class);
  private final AddSshKey restAddSshKey;
  private final GetSshKeys restGetSshKeys;
  private final AccountManager accountManager;
  private final AccountCache accountCache;
  private final PutPreferred putPreferred;
  private final PutName putName;
  private final Provider<AccountsUpdate> accountsUpdateProvider;
  private final ExternalIds externalIds;

  @Inject
  public AccountController(
      final AddSshKey restAddSshKey,
      final GetSshKeys restGetSshKeys,
      final AccountManager accountManager,
      final AccountCache accountCache,
      final PutPreferred putPreferred,
      final PutName putName,
      @ServerInitiated final Provider<AccountsUpdate> accountsUpdateProvider,
      final ExternalIds externalIds) {
    this.restAddSshKey = restAddSshKey;
    this.restGetSshKeys = restGetSshKeys;
    this.accountManager = accountManager;
    this.accountCache = accountCache;
    this.putPreferred = putPreferred;
    this.putName = putName;
    this.accountsUpdateProvider = accountsUpdateProvider;
    this.externalIds = externalIds;
  }

  @Override
  public void doAction(
      IdentifiedUser user,
      GitHubLogin hubLogin,
      HttpServletRequest req,
      HttpServletResponse resp,
      ControllerErrors errors)
      throws ServletException, IOException {
    try {
      setAccountIdentity(user, req);
      setAccoutPublicKeys(user, hubLogin, req);

      log.info(
          "Updated account '"
              + user.getAccountId()
              + "' with username='"
              + req.getParameter("username")
              + "'");
    } catch (IOException | ConfigInvalidException e) {
      log.error("Account '" + user.getUserName() + "' creation failed", e);
      throw new IOException(e);
    }
  }

  private void setAccountIdentity(IdentifiedUser user, HttpServletRequest req)
      throws ServletException, ConfigInvalidException {
    String fullName = req.getParameter("fullname");
    String email = req.getParameter("email");
    String username = req.getParameter("username");
    try {
      Id accountId = user.getAccountId();
      AuthResult result = accountManager.link(accountId, AuthRequest.forEmail(email));
      log.debug("Account {} linked to email {}: result = {}", accountId, email, result);

      putPreferred.apply(new AccountResource.Email(user, email), null);
      NameInput nameInput = new NameInput();
      nameInput.name = fullName;
      putName.apply(user, nameInput);

      ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, username);
      Optional<ExternalId> other;
      try {
        other = externalIds.get(key);
      } catch (IOException | ConfigInvalidException e) {
        throw new IllegalArgumentException(
            "Internal error while fetching username='" + username + "'");
      }

      if (other.map(externalId -> externalId.accountId().equals(accountId)).orElse(false)) {
        // Current account has already an external id with SCHEME_USERNAME set to the username
        return;
      }

      try {
        accountsUpdateProvider
            .get()
            .update(
                "Set Username from GitHub",
                accountId,
                u -> u.addExternalId(ExternalId.create(key, accountId, null, null)));
      } catch (Exception e) {
        throw new IllegalArgumentException(
            "Internal error while trying to set username='" + username + "'");
      }

      log.debug(
          "Account {} updated with preferredEmail = {}, fullName = {}, username = {}",
          accountId,
          email,
          fullName,
          username);

      accountCache.evict(accountId);
      log.debug("Account cache evicted for {}", accountId);
    } catch (Exception e) {
      throw new ServletException(
          "Cannot associate email '" + email + "' to current user '" + user + "'", e);
    }
  }

  private void setAccoutPublicKeys(
      IdentifiedUser user, GitHubLogin hubLogin, HttpServletRequest req) throws IOException {
    GHMyself myself = hubLogin.getMyself();
    List<GHVerifiedKey> githubKeys = myself.getPublicVerifiedKeys();
    HashSet<String> gerritKeys = Sets.newHashSet(getCurrentGerritSshKeys(user));
    for (GHKey ghKey : githubKeys) {
      String sshKeyCheckedParam = "key_check_" + ghKey.getId();
      String sshKeyWithLabel = ghKey.getKey() + " " + ghKey.getTitle();
      String checked = req.getParameter(sshKeyCheckedParam);
      if (checked != null
          && checked.equalsIgnoreCase("on")
          && !gerritKeys.contains(ghKey.getKey())) {
        addSshKey(user, sshKeyWithLabel);
        gerritKeys.add(ghKey.getKey());
      }
    }
  }

  private List<String> getCurrentGerritSshKeys(final IdentifiedUser user) throws IOException {
    AccountResource res = new AccountResource(user);
    try {
      List<SshKeyInfo> keysInfo = restGetSshKeys.apply(res).value();
      return Lists.transform(
          keysInfo,
          new Function<SshKeyInfo, String>() {

            @Override
            public String apply(SshKeyInfo keyInfo) {
              return StringUtils.substringBeforeLast(keyInfo.sshPublicKey, " ");
            }
          });
    } catch (Exception e) {
      log.error("User list keys failed", e);
      throw new IOException("Cannot get list of user keys", e);
    }
  }

  private void addSshKey(final IdentifiedUser user, final String sshKeyWithLabel)
      throws IOException {
    AccountResource res = new AccountResource(user);
    final ByteArrayInputStream keyIs = new ByteArrayInputStream(sshKeyWithLabel.getBytes());
    SshKeyInput key = new SshKeyInput();
    key.raw =
        new RawInput() {

          @Override
          public InputStream getInputStream() throws IOException {
            return keyIs;
          }

          @Override
          public String getContentType() {
            return "text/plain";
          }

          @Override
          public long getContentLength() {
            return sshKeyWithLabel.length();
          }
        };
    try {
      restAddSshKey.apply(res, key);
    } catch (Exception e) {
      log.error("Add key " + sshKeyWithLabel + " failed", e);
      throw new IOException("Cannot store SSH Key '" + sshKeyWithLabel + "'", e);
    }
  }
}
