/*
 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.lib;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.SystemReader;
import org.eclipse.jgit.util.time.ProposedTimestamp;

/**
 * A combination of a person identity and time in Git.
 *
 * Git combines Name + email + time + time zone to specify who wrote or
 * committed something.
 */
public class PersonIdent implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * Get timezone object for the given offset.
	 *
	 * @param tzOffset
	 *            timezone offset as in {@link #getTimeZoneOffset()}.
	 * @return time zone object for the given offset.
	 * @since 4.1
	 */
	public static TimeZone getTimeZone(int tzOffset) {
		StringBuilder tzId = new StringBuilder(8);
		tzId.append("GMT"); //$NON-NLS-1$
		appendTimezone(tzId, tzOffset);
		return TimeZone.getTimeZone(tzId.toString());
	}

	/**
	 * Format a timezone offset.
	 *
	 * @param r
	 *            string builder to append to.
	 * @param offset
	 *            timezone offset as in {@link #getTimeZoneOffset()}.
	 * @since 4.1
	 */
	public static void appendTimezone(StringBuilder r, int offset) {
		final char sign;
		final int offsetHours;
		final int offsetMins;

		if (offset < 0) {
			sign = '-';
			offset = -offset;
		} else {
			sign = '+';
		}

		offsetHours = offset / 60;
		offsetMins = offset % 60;

		r.append(sign);
		if (offsetHours < 10) {
			r.append('0');
		}
		r.append(offsetHours);
		if (offsetMins < 10) {
			r.append('0');
		}
		r.append(offsetMins);
	}

	/**
	 * Sanitize the given string for use in an identity and append to output.
	 * <p>
	 * Trims whitespace from both ends and special characters {@code \n < >} that
	 * interfere with parsing; appends all other characters to the output.
	 * Analogous to the C git function {@code strbuf_addstr_without_crud}.
	 *
	 * @param r
	 *            string builder to append to.
	 * @param str
	 *            input string.
	 * @since 4.4
	 */
	public static void appendSanitized(StringBuilder r, String str) {
		// Trim any whitespace less than \u0020 as in String#trim().
		int i = 0;
		while (i < str.length() && str.charAt(i) <= ' ') {
			i++;
		}
		int end = str.length();
		while (end > i && str.charAt(end - 1) <= ' ') {
			end--;
		}

		for (; i < end; i++) {
			char c = str.charAt(i);
			switch (c) {
				case '\n':
				case '<':
				case '>':
					continue;
				default:
					r.append(c);
					break;
			}
		}
	}

	private final String name;

	private final String emailAddress;

	private final long when;

	private final int tzOffset;

	/**
	 * Creates new PersonIdent from config info in repository, with current time.
	 * This new PersonIdent gets the info from the default committer as available
	 * from the configuration.
	 *
	 * @param repo a {@link org.eclipse.jgit.lib.Repository} object.
	 */
	public PersonIdent(Repository repo) {
		this(repo.getConfig().get(UserConfig.KEY));
	}

	/**
	 * Copy a {@link org.eclipse.jgit.lib.PersonIdent}.
	 *
	 * @param pi
	 *            Original {@link org.eclipse.jgit.lib.PersonIdent}
	 */
	public PersonIdent(PersonIdent pi) {
		this(pi.getName(), pi.getEmailAddress());
	}

	/**
	 * Construct a new {@link org.eclipse.jgit.lib.PersonIdent} with current
	 * time.
	 *
	 * @param aName
	 *            a {@link java.lang.String} object.
	 * @param aEmailAddress
	 *            a {@link java.lang.String} object.
	 */
	public PersonIdent(String aName, String aEmailAddress) {
		this(aName, aEmailAddress, SystemReader.getInstance().getCurrentTime());
	}

	/**
	 * Construct a new {@link org.eclipse.jgit.lib.PersonIdent} with current
	 * time.
	 *
	 * @param aName
	 *            a {@link java.lang.String} object.
	 * @param aEmailAddress
	 *            a {@link java.lang.String} object.
	 * @param when
	 *            a {@link org.eclipse.jgit.util.time.ProposedTimestamp} object.
	 * @since 4.6
	 */
	public PersonIdent(String aName, String aEmailAddress,
			ProposedTimestamp when) {
		this(aName, aEmailAddress, when.millis());
	}

	/**
	 * Copy a PersonIdent, but alter the clone's time stamp
	 *
	 * @param pi
	 *            original {@link org.eclipse.jgit.lib.PersonIdent}
	 * @param when
	 *            local time
	 * @param tz
	 *            time zone
	 */
	public PersonIdent(PersonIdent pi, Date when, TimeZone tz) {
		this(pi.getName(), pi.getEmailAddress(), when, tz);
	}

	/**
	 * Copy a {@link org.eclipse.jgit.lib.PersonIdent}, but alter the clone's
	 * time stamp
	 *
	 * @param pi
	 *            original {@link org.eclipse.jgit.lib.PersonIdent}
	 * @param aWhen
	 *            local time
	 */
	public PersonIdent(PersonIdent pi, Date aWhen) {
		this(pi.getName(), pi.getEmailAddress(), aWhen.getTime(), pi.tzOffset);
	}

	/**
	 * Copy a {@link org.eclipse.jgit.lib.PersonIdent}, but alter the clone's
	 * time stamp
	 *
	 * @param pi
	 *            original {@link org.eclipse.jgit.lib.PersonIdent}
	 * @param aWhen
	 *            local time as Instant
	 * @since 6.1
	 */
	public PersonIdent(PersonIdent pi, Instant aWhen) {
		this(pi.getName(), pi.getEmailAddress(), aWhen.toEpochMilli(), pi.tzOffset);
	}

	/**
	 * Construct a PersonIdent from simple data
	 *
	 * @param aName a {@link java.lang.String} object.
	 * @param aEmailAddress a {@link java.lang.String} object.
	 * @param aWhen
	 *            local time stamp
	 * @param aTZ
	 *            time zone
	 */
	public PersonIdent(final String aName, final String aEmailAddress,
			final Date aWhen, final TimeZone aTZ) {
		this(aName, aEmailAddress, aWhen.getTime(), aTZ.getOffset(aWhen
				.getTime()) / (60 * 1000));
	}

	/**
	 * Construct a PersonIdent from simple data
	 *
	 * @param aName
	 *            a {@link java.lang.String} object.
	 * @param aEmailAddress
	 *            a {@link java.lang.String} object.
	 * @param aWhen
	 *            local time stamp
	 * @param zoneId
	 *            time zone id
	 * @since 6.1
	 */
	public PersonIdent(final String aName, String aEmailAddress, Instant aWhen,
			ZoneId zoneId) {
		this(aName, aEmailAddress, aWhen.toEpochMilli(),
				TimeZone.getTimeZone(zoneId)
						.getOffset(aWhen
				.toEpochMilli()) / (60 * 1000));
	}

	/**
	 * Copy a PersonIdent, but alter the clone's time stamp
	 *
	 * @param pi
	 *            original {@link org.eclipse.jgit.lib.PersonIdent}
	 * @param aWhen
	 *            local time stamp
	 * @param aTZ
	 *            time zone
	 */
	public PersonIdent(PersonIdent pi, long aWhen, int aTZ) {
		this(pi.getName(), pi.getEmailAddress(), aWhen, aTZ);
	}

	private PersonIdent(final String aName, final String aEmailAddress,
			long when) {
		this(aName, aEmailAddress, when, SystemReader.getInstance()
				.getTimezone(when));
	}

	private PersonIdent(UserConfig config) {
		this(config.getCommitterName(), config.getCommitterEmail());
	}

	/**
	 * Construct a {@link org.eclipse.jgit.lib.PersonIdent}.
	 * <p>
	 * Whitespace in the name and email is preserved for the lifetime of this
	 * object, but are trimmed by {@link #toExternalString()}. This means that
	 * parsing the result of {@link #toExternalString()} may not return an
	 * equivalent instance.
	 *
	 * @param aName
	 *            a {@link java.lang.String} object.
	 * @param aEmailAddress
	 *            a {@link java.lang.String} object.
	 * @param aWhen
	 *            local time stamp
	 * @param aTZ
	 *            time zone
	 */
	public PersonIdent(final String aName, final String aEmailAddress,
			final long aWhen, final int aTZ) {
		if (aName == null)
			throw new IllegalArgumentException(
					JGitText.get().personIdentNameNonNull);
		if (aEmailAddress == null)
			throw new IllegalArgumentException(
					JGitText.get().personIdentEmailNonNull);
		name = aName;
		emailAddress = aEmailAddress;
		when = aWhen;
		tzOffset = aTZ;
	}

	/**
	 * Get name of person
	 *
	 * @return Name of person
	 */
	public String getName() {
		return name;
	}

	/**
	 * Get email address of person
	 *
	 * @return email address of person
	 */
	public String getEmailAddress() {
		return emailAddress;
	}

	/**
	 * Get timestamp
	 *
	 * @return timestamp
	 */
	public Date getWhen() {
		return new Date(when);
	}

	/**
	 * Get when attribute as instant
	 *
	 * @return timestamp
	 * @since 6.1
	 */
	public Instant getWhenAsInstant() {
		return Instant.ofEpochMilli(when);
	}

	/**
	 * Get this person's declared time zone
	 *
	 * @return this person's declared time zone; null if time zone is unknown.
	 */
	public TimeZone getTimeZone() {
		return getTimeZone(tzOffset);
	}

	/**
	 * Get the time zone id
	 *
	 * @return the time zone id
	 * @since 6.1
	 */
	public ZoneId getZoneId() {
		return getTimeZone().toZoneId();
	}

	/**
	 * Get this person's declared time zone as minutes east of UTC.
	 *
	 * @return this person's declared time zone as minutes east of UTC. If the
	 *         timezone is to the west of UTC it is negative.
	 */
	public int getTimeZoneOffset() {
		return tzOffset;
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Hashcode is based only on the email address and timestamp.
	 */
	@Override
	public int hashCode() {
		int hc = getEmailAddress().hashCode();
		hc *= 31;
		hc += (int) (when / 1000L);
		return hc;
	}

	@Override
	public boolean equals(Object o) {
		if (o instanceof PersonIdent) {
			final PersonIdent p = (PersonIdent) o;
			return getName().equals(p.getName())
					&& getEmailAddress().equals(p.getEmailAddress())
					&& when / 1000L == p.when / 1000L;
		}
		return false;
	}

	/**
	 * Format for Git storage.
	 *
	 * @return a string in the git author format
	 */
	public String toExternalString() {
		final StringBuilder r = new StringBuilder();
		appendSanitized(r, getName());
		r.append(" <"); //$NON-NLS-1$
		appendSanitized(r, getEmailAddress());
		r.append("> "); //$NON-NLS-1$
		r.append(when / 1000);
		r.append(' ');
		appendTimezone(r, tzOffset);
		return r.toString();
	}

	@Override
	@SuppressWarnings("nls")
	public String toString() {
		final StringBuilder r = new StringBuilder();
		final SimpleDateFormat dtfmt;
		dtfmt = new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy Z", Locale.US);
		dtfmt.setTimeZone(getTimeZone());

		r.append("PersonIdent[");
		r.append(getName());
		r.append(", ");
		r.append(getEmailAddress());
		r.append(", ");
		r.append(dtfmt.format(Long.valueOf(when)));
		r.append("]");

		return r.toString();
	}
}

