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

import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import com.google.gerrit.common.Nullable;

/** Represents an address (name + email) in an email message. */
@AutoValue
public abstract class Address {
  public static Address parse(String in) {
    final int lt = in.indexOf('<');
    final int gt = in.indexOf('>');
    final int at = in.indexOf("@");
    if (0 <= lt && lt < gt && lt + 1 < at && at + 1 < gt) {
      final String email = in.substring(lt + 1, gt).trim();
      final String name = in.substring(0, lt).trim();
      int nameStart = 0;
      int nameEnd = name.length();
      if (name.startsWith("\"")) {
        nameStart++;
      }
      if (name.endsWith("\"")) {
        nameEnd--;
      }
      return Address.create(name.length() > 0 ? name.substring(nameStart, nameEnd) : null, email);
    }

    if (lt < 0 && gt < 0 && 0 < at && at < in.length() - 1) {
      return Address.create(in);
    }

    throw new IllegalArgumentException("Invalid email address: " + in);
  }

  public static Address tryParse(String in) {
    try {
      return parse(in);
    } catch (IllegalArgumentException e) {
      return null;
    }
  }

  public static Address create(String email) {
    return create(null, email);
  }

  public static Address create(String name, String email) {
    return new AutoValue_Address(name, email);
  }

  @Nullable
  public abstract String name();

  public abstract String email();

  @Memoized
  @Override
  public int hashCode() {
    return email().hashCode();
  }

  @Override
  public final boolean equals(Object other) {
    if (other instanceof Address) {
      return email().equals(((Address) other).email());
    }
    return false;
  }

  @Override
  public final String toString() {
    return toHeaderString();
  }

  public String toHeaderString() {
    if (name() != null) {
      return quotedPhrase(name()) + " <" + email() + ">";
    } else if (isSimple()) {
      return email();
    }
    return "<" + email() + ">";
  }

  private static final String MUST_QUOTE_EMAIL = "()<>,;:\\\"[]";
  private static final String MUST_QUOTE_NAME = MUST_QUOTE_EMAIL + "@.";

  private boolean isSimple() {
    for (int i = 0; i < email().length(); i++) {
      final char c = email().charAt(i);
      if (c <= ' ' || 0x7F <= c || MUST_QUOTE_EMAIL.indexOf(c) != -1) {
        return false;
      }
    }
    return true;
  }

  private static String quotedPhrase(String name) {
    if (EmailHeader.needsQuotedPrintable(name)) {
      return EmailHeader.quotedPrintable(name);
    }
    for (int i = 0; i < name.length(); i++) {
      final char c = name.charAt(i);
      if (MUST_QUOTE_NAME.indexOf(c) != -1) {
        return wrapInQuotes(name);
      }
    }
    return name;
  }

  private static String wrapInQuotes(String name) {
    final StringBuilder r = new StringBuilder(2 + name.length());
    r.append('"');
    for (int i = 0; i < name.length(); i++) {
      char c = name.charAt(i);
      if (c == '"' || c == '\\') {
        r.append('\\');
      }
      r.append(c);
    }
    r.append('"');
    return r.toString();
  }
}
