/*
 * Copyright (C) 2006, 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * Copyright (C) 2010, 2020, Chris Aniszczyk <caniszczyk@gmail.com> 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 static java.nio.charset.StandardCharsets.UTF_8;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.util.References;

/**
 * Mutable builder to construct an annotated tag recording a project state.
 *
 * Applications should use this object when they need to manually construct a
 * tag and want precise control over its fields.
 *
 * To read a tag object, construct a {@link org.eclipse.jgit.revwalk.RevWalk}
 * and obtain a {@link org.eclipse.jgit.revwalk.RevTag} instance by calling
 * {@link org.eclipse.jgit.revwalk.RevWalk#parseTag(AnyObjectId)}.
 */
public class TagBuilder extends ObjectBuilder {

	private static final byte[] hobject = Constants.encodeASCII("object"); //$NON-NLS-1$

	private static final byte[] htype = Constants.encodeASCII("type"); //$NON-NLS-1$

	private static final byte[] htag = Constants.encodeASCII("tag"); //$NON-NLS-1$

	private static final byte[] htagger = Constants.encodeASCII("tagger"); //$NON-NLS-1$

	private ObjectId object;

	private int type = Constants.OBJ_BAD;

	private String tag;

	/**
	 * Get the type of object this tag refers to.
	 *
	 * @return the type of object this tag refers to.
	 */
	public int getObjectType() {
		return type;
	}

	/**
	 * Get the object this tag refers to.
	 *
	 * @return the object this tag refers to.
	 */
	public ObjectId getObjectId() {
		return object;
	}

	/**
	 * Set the object this tag refers to, and its type.
	 *
	 * @param obj
	 *            the object.
	 * @param objType
	 *            the type of {@code obj}. Must be a valid type code.
	 */
	public void setObjectId(AnyObjectId obj, int objType) {
		object = obj.copy();
		type = objType;
	}

	/**
	 * Set the object this tag refers to, and infer its type.
	 *
	 * @param obj
	 *            the object the tag will refer to.
	 */
	public void setObjectId(RevObject obj) {
		setObjectId(obj, obj.getType());
	}

	/**
	 * Get short name of the tag (no {@code refs/tags/} prefix).
	 *
	 * @return short name of the tag (no {@code refs/tags/} prefix).
	 */
	public String getTag() {
		return tag;
	}

	/**
	 * Set the name of this tag.
	 *
	 * @param shortName
	 *            new short name of the tag. This short name should not start
	 *            with {@code refs/} as typically a tag is stored under the
	 *            reference derived from {@code "refs/tags/" + getTag()}.
	 */
	public void setTag(String shortName) {
		this.tag = shortName;
	}

	/**
	 * Get creator of this tag.
	 *
	 * @return creator of this tag. May be null.
	 */
	public PersonIdent getTagger() {
		return getAuthor();
	}

	/**
	 * Set the creator of this tag.
	 *
	 * @param taggerIdent
	 *            the creator. May be null.
	 */
	public void setTagger(PersonIdent taggerIdent) {
		setAuthor(taggerIdent);
	}

	/**
	 * Format this builder's state as an annotated tag object.
	 *
	 * @return this object in the canonical annotated tag format, suitable for
	 *         storage in a repository.
	 */
	@Override
	public byte[] build() throws UnsupportedEncodingException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try (OutputStreamWriter w = new OutputStreamWriter(os,
				getEncoding())) {

			os.write(hobject);
			os.write(' ');
			getObjectId().copyTo(os);
			os.write('\n');

			os.write(htype);
			os.write(' ');
			os.write(Constants
					.encodeASCII(Constants.typeString(getObjectType())));
			os.write('\n');

			os.write(htag);
			os.write(' ');
			w.write(getTag());
			w.flush();
			os.write('\n');

			if (getTagger() != null) {
				os.write(htagger);
				os.write(' ');
				w.write(getTagger().toExternalString());
				w.flush();
				os.write('\n');
			}

			writeEncoding(getEncoding(), os);

			os.write('\n');
			String msg = getMessage();
			if (msg != null) {
				w.write(msg);
				w.flush();
			}

			GpgSignature signature = getGpgSignature();
			if (signature != null) {
				if (msg != null && !msg.isEmpty() && !msg.endsWith("\n")) { //$NON-NLS-1$
					// If signed, the message *must* end with a linefeed
					// character, otherwise signature verification will fail.
					// (The signature will have been computed over the payload
					// containing the message without LF, but will be verified
					// against a payload with the LF.) The signature must start
					// on a new line.
					throw new JGitInternalException(
							JGitText.get().signedTagMessageNoLf);
				}
				String externalForm = signature.toExternalString();
				w.write(externalForm);
				w.flush();
				if (!externalForm.endsWith("\n")) { //$NON-NLS-1$
					os.write('\n');
				}
			}
		} catch (IOException err) {
			// This should never occur, the only way to get it above is
			// for the ByteArrayOutputStream to throw, but it doesn't.
			//
			throw new RuntimeException(err);
		}
		return os.toByteArray();
	}

	/**
	 * Format this builder's state as an annotated tag object.
	 *
	 * @return this object in the canonical annotated tag format, suitable for
	 *         storage in a repository, or {@code null} if the tag cannot be
	 *         encoded
	 * @deprecated since 5.11; use {@link #build()} instead
	 */
	@Deprecated
	public byte[] toByteArray() {
		try {
			return build();
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	/** {@inheritDoc} */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		StringBuilder r = new StringBuilder();
		r.append("Tag");
		r.append("={\n");

		r.append("object ");
		r.append(object != null ? object.name() : "NOT_SET");
		r.append("\n");

		r.append("type ");
		r.append(object != null ? Constants.typeString(type) : "NOT_SET");
		r.append("\n");

		r.append("tag ");
		r.append(tag != null ? tag : "NOT_SET");
		r.append("\n");

		if (getTagger() != null) {
			r.append("tagger ");
			r.append(getTagger());
			r.append("\n");
		}

		Charset encoding = getEncoding();
		if (!References.isSameObject(encoding, UTF_8)) {
			r.append("encoding ");
			r.append(encoding.name());
			r.append("\n");
		}

		r.append("\n");
		r.append(getMessage() != null ? getMessage() : "");
		GpgSignature signature = getGpgSignature();
		r.append(signature != null ? signature.toExternalString() : "");
		r.append("}");
		return r.toString();
	}
}
