// Copyright (C) 2009 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.google.gerrit.server.mail.send;

import static java.util.Objects.requireNonNull;

import com.google.gerrit.entities.Address;
import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.mail.EmailTokenVerifier;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

/**
 * Sender that informs a user by email about the registration of a new email address for their
 * account.
 */
public class RegisterNewEmailSender extends OutgoingEmail {
  public interface Factory {
    RegisterNewEmailSender create(String address);
  }

  private final EmailTokenVerifier tokenVerifier;
  private final IdentifiedUser user;
  private final String addr;
  private String emailToken;

  @Inject
  public RegisterNewEmailSender(
      EmailArguments args,
      EmailTokenVerifier tokenVerifier,
      IdentifiedUser callingUser,
      @Assisted final String address) {
    super(args, "registernewemail");
    this.tokenVerifier = tokenVerifier;
    this.user = callingUser;
    this.addr = address;
  }

  @Override
  protected void init() throws EmailException {
    super.init();
    setHeader("Subject", "[Gerrit Code Review] Email Verification");
    addByEmail(RecipientType.TO, Address.create(addr));
  }

  @Override
  protected void format() throws EmailException {
    appendText(textTemplate("RegisterNewEmail"));
    if (useHtml()) {
      appendHtml(soyHtmlTemplate("RegisterNewEmailHtml"));
    }
  }

  public boolean isAllowed() {
    return args.emailSender.canEmail(addr);
  }

  @Override
  protected void setupSoyContext() {
    super.setupSoyContext();
    soyContextEmailData.put("emailRegistrationToken", getEmailRegistrationToken());
    soyContextEmailData.put("userNameEmail", getUserNameEmailFor(user.getAccountId()));
  }

  private String getEmailRegistrationToken() {
    if (emailToken == null) {
      emailToken = requireNonNull(tokenVerifier.encode(user.getAccountId(), addr), "token");
    }
    return emailToken;
  }
}
