/*******************************************************************************
 * Copyright (c) 2007, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which accompanies this distribution,
 * and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors: IBM Corporation - initial API and implementation
 ******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;

import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.osgi.signedcontent.InvalidContentException;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignedContentEntry;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;

public class SignedContentImpl implements SignedContent {
	final static int VERIFY_LIMIT = 1000 * 1024; // 1 mb; not sure what the best limit is
	final static SignerInfo[] EMPTY_SIGNERINFO = new SignerInfo[0];
	// the content which is signed
	volatile SignedBundleFile content; // TODO can this be more general?
	// the content entry md results used for entry content verification
	// keyed by entry path -> {SignerInfo[] infos, byte[][] results)}
	private final Map<String, Object> contentMDResults;
	private final SignerInfo[] signerInfos;
	// map of tsa singers keyed by SignerInfo -> {tsa_SignerInfo, signingTime}
	private Map<SignerInfo, Object[]> tsaSignerInfos;
	volatile private boolean checkedValid = false;

	public SignedContentImpl(SignerInfo[] signerInfos, Map<String, Object> contentMDResults) {
		this.signerInfos = signerInfos == null ? EMPTY_SIGNERINFO : signerInfos;
		this.contentMDResults = contentMDResults;
	}

	@Override
	public SignedContentEntry[] getSignedEntries() {
		if (contentMDResults == null)
			return new SignedContentEntry[0];
		List<SignedContentEntry> results = new ArrayList<>(contentMDResults.size());
		for (Map.Entry<String, Object> entry : contentMDResults.entrySet()) {
			String entryName = entry.getKey();
			Object[] mdResult = (Object[]) entry.getValue();
			results.add(new SignedContentEntryImpl(entryName, (SignerInfo[]) mdResult[0]));
		}
		return results.toArray(new SignedContentEntry[results.size()]);
	}

	@Override
	public SignedContentEntry getSignedEntry(String name) {
		if (contentMDResults == null)
			return null;
		Object[] mdResult = (Object[]) contentMDResults.get(name);
		return mdResult == null ? null : new SignedContentEntryImpl(name, (SignerInfo[]) mdResult[0]);
	}

	@Override
	public SignerInfo[] getSignerInfos() {
		return signerInfos;
	}

	@Override
	public Date getSigningTime(SignerInfo signerInfo) {
		if (tsaSignerInfos == null)
			return null;
		Object[] tsaInfo = tsaSignerInfos.get(signerInfo);
		return tsaInfo == null ? null : (Date) tsaInfo[1];
	}

	@Override
	public SignerInfo getTSASignerInfo(SignerInfo signerInfo) {
		if (tsaSignerInfos == null)
			return null;
		Object[] tsaInfo = tsaSignerInfos.get(signerInfo);
		return tsaInfo == null ? null : (SignerInfo) tsaInfo[0];
	}

	@Override
	public boolean isSigned() {
		return signerInfos.length > 0;
	}

	@Override
	public void checkValidity(SignerInfo signer) throws CertificateExpiredException, CertificateNotYetValidException {
		Date signingTime = getSigningTime(signer);
		if (checkedValid)
			return;
		Certificate[] certs = signer.getCertificateChain();
		for (Certificate cert : certs) {
			if (!(cert instanceof X509Certificate)) {
				continue;
			}
			if (signingTime == null) {
				((X509Certificate) cert).checkValidity();
			} else {
				((X509Certificate) cert).checkValidity(signingTime);
			}
		}
		checkedValid = true;
	}

	void setContent(SignedBundleFile content) {
		this.content = content;
	}

	void setTSASignerInfos(Map<SignerInfo, Object[]> tsaSignerInfos) {
		this.tsaSignerInfos = tsaSignerInfos;
	}

	void addTSASignerInfo(SignerInfo baseInfo, SignerInfo tsaSignerInfo, Date signingTime) {
		// sanity check to make sure the baseInfo is here
		if (!containsInfo(baseInfo))
			throw new IllegalArgumentException("The baseInfo is not found"); //$NON-NLS-1$
		if (tsaSignerInfos == null)
			tsaSignerInfos = new HashMap<>(signerInfos.length);
		tsaSignerInfos.put(baseInfo, new Object[] {tsaSignerInfo, signingTime});
	}

	Map<String, Object> getContentMDResults() {
		return contentMDResults;
	}

	private boolean containsInfo(SignerInfo signerInfo) {
		for (SignerInfo si : signerInfos) {
			if (signerInfo == si) {
				return true;
			}
		}
		return false;
	}

	InputStream getDigestInputStream(BundleEntry nestedEntry) throws IOException {
		if (contentMDResults == null)
			return nestedEntry.getInputStream();
		Object[] mdResult = (Object[]) contentMDResults.get(nestedEntry.getName());
		if (mdResult == null)
			return null;
		try {
			return new DigestedInputStream(nestedEntry, content, (SignerInfo[]) mdResult[0], (byte[][]) mdResult[1], nestedEntry.getSize());
		} catch (NoSuchAlgorithmException e) {
			throw new IOException(e);
		}
	}

	public class SignedContentEntryImpl implements SignedContentEntry {
		private final String entryName;
		private final SignerInfo[] entrySigners;

		public SignedContentEntryImpl(String entryName, SignerInfo[] entrySigners) {
			this.entryName = entryName;
			this.entrySigners = entrySigners == null ? EMPTY_SIGNERINFO : entrySigners;
		}

		@Override
		public String getName() {
			return entryName;
		}

		@Override
		public SignerInfo[] getSignerInfos() {
			return entrySigners;
		}

		@Override
		public boolean isSigned() {
			return entrySigners.length > 0;
		}

		@Override
		public void verify() throws IOException, InvalidContentException {
			BundleFile currentContent = content;
			if (currentContent == null)
				throw new InvalidContentException("The content was not set", null); //$NON-NLS-1$
			BundleEntry entry = null;
			SecurityException exception = null;
			try {
				entry = currentContent.getEntry(entryName);
			} catch (SecurityException e) {
				exception = e;
			}
			if (entry == null)
				throw new InvalidContentException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, entryName, String.valueOf(currentContent.getBaseFile())), exception);

			if (entry.getSize() > VERIFY_LIMIT) {
				try (InputStream in = entry.getInputStream()) {
					final byte[] buf = new byte[1024];
					while (in.read(buf) > 0) {
						// just exhausting the stream to verify
					}
				}
			} else {
				entry.getBytes();
			}
		}
	}
}
