// Copyright (C) 2012 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;

import com.google.gerrit.entities.Account;
import com.google.gerrit.server.account.AuthRequest;

/** Verifies the token used by new email address verification process. */
public interface EmailTokenVerifier {
  /**
   * Construct a token to verify an email address for a user.
   *
   * @param accountId the caller that wants to add an email to their account.
   * @param emailAddress the address to add.
   * @return an unforgeable string to email to {@code emailAddress}. Presenting the string provides
   *     proof the user has the ability to read messages sent to that address. Must not be null.
   */
  String encode(Account.Id accountId, String emailAddress);

  /**
   * Decode a token previously created.
   *
   * @param tokenString the string created by encode. Never null.
   * @return a pair of account id and email address.
   * @throws InvalidTokenException the token is invalid, expired, malformed, etc.
   */
  ParsedToken decode(String tokenString) throws InvalidTokenException;

  /** Exception thrown when a token does not parse correctly. */
  class InvalidTokenException extends Exception {
    private static final long serialVersionUID = 1L;

    public InvalidTokenException() {
      super("Invalid token");
    }

    public InvalidTokenException(Throwable cause) {
      super("Invalid token", cause);
    }
  }

  /** Pair returned from decode to provide the data used during encode. */
  class ParsedToken {
    private final Account.Id accountId;
    private final String emailAddress;
    private final AuthRequest.Factory authRequestFactory;

    public ParsedToken(
        Account.Id accountId, String emailAddress, AuthRequest.Factory authRequestFactory) {
      this.accountId = accountId;
      this.emailAddress = emailAddress;
      this.authRequestFactory = authRequestFactory;
    }

    public Account.Id getAccountId() {
      return accountId;
    }

    public String getEmailAddress() {
      return emailAddress;
    }

    public AuthRequest toAuthRequest() {
      return authRequestFactory.createForEmail(getEmailAddress());
    }

    @Override
    public String toString() {
      return accountId + " adds " + emailAddress;
    }
  }
}
