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

import com.google.gerrit.common.data.ParamertizedString;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent;

/** Creates a {@link FromAddressGenerator} from the {@link GerritServerConfig} */
@Singleton
public class FromAddressGeneratorProvider implements
    Provider<FromAddressGenerator> {
  private final FromAddressGenerator generator;

  @Inject
  FromAddressGeneratorProvider(@GerritServerConfig final Config cfg,
      @GerritPersonIdent final PersonIdent myIdent,
      final AccountCache accountCache) {

    final String from = cfg.getString("sendemail", null, "from");
    final Address srvAddr = toAddress(myIdent);

    if (from == null || "MIXED".equalsIgnoreCase(from)) {
      final String name = "${user} (Code Review)";
      final String email = srvAddr.email;
      generator = new PatternGen(srvAddr, accountCache, name, email);

    } else if ("USER".equalsIgnoreCase(from)) {
      generator = new UserGen(accountCache, srvAddr);

    } else if ("SERVER".equalsIgnoreCase(from)) {
      generator = new ServerGen(srvAddr);

    } else {
      final Address a = Address.parse(from);
      generator = new PatternGen(srvAddr, accountCache, a.name, a.email);
    }
  }

  private static Address toAddress(final PersonIdent myIdent) {
    return new Address(myIdent.getName(), myIdent.getEmailAddress());
  }

  @Override
  public FromAddressGenerator get() {
    return generator;
  }

  static final class UserGen implements FromAddressGenerator {
    private final AccountCache accountCache;
    private final Address srvAddr;

    UserGen(AccountCache accountCache, Address srvAddr) {
      this.accountCache = accountCache;
      this.srvAddr = srvAddr;
    }

    @Override
    public Address from(final Account.Id fromId) {
      if (fromId != null) {
        final Account a = accountCache.get(fromId).getAccount();
        if (a.getPreferredEmail() != null) {
          return new Address(a.getFullName(), a.getPreferredEmail());
        }
      }
      return srvAddr;
    }
  }

  static final class ServerGen implements FromAddressGenerator {
    private final Address srvAddr;

    ServerGen(Address srvAddr) {
      this.srvAddr = srvAddr;
    }

    @Override
    public Address from(final Account.Id fromId) {
      return srvAddr;
    }
  }

  static final class PatternGen implements FromAddressGenerator {
    private final String senderEmail;
    private final Address serverAddress;
    private final AccountCache accountCache;
    private final ParamertizedString namePattern;

    PatternGen(final Address serverAddress, final AccountCache accountCache,
        final String namePattern, final String senderEmail) {
      this.senderEmail = senderEmail;
      this.serverAddress = serverAddress;
      this.accountCache = accountCache;
      this.namePattern = new ParamertizedString(namePattern);
    }

    @Override
    public Address from(final Account.Id fromId) {
      final String senderName;

      if (fromId != null) {
        final Account account = accountCache.get(fromId).getAccount();
        String fullName = account.getFullName();
        if (fullName == null || "".equals(fullName)) {
          fullName = "Anonymous Coward";
        }
        senderName = namePattern.replace("user", fullName).toString();

      } else {
        senderName = serverAddress.name;
      }

      return new Address(senderName, senderEmail);
    }
  }
}
