/*-
 * Copyright 2003-2005 Colin Percival
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted providing that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#if 0
__FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 cperciva Exp $");
#endif

#include "bsdiff/bsdiff.h"

#include <sys/types.h>

#include <err.h>
#include <string.h>

#include <algorithm>

#include "bsdiff/diff_encoder.h"
#include "bsdiff/patch_writer.h"
#include "bsdiff/suffix_array_index.h"

namespace bsdiff {

// TODO(deymo): Deprecate this version of the interface and move all callers
// to the underlying version using PatchWriterInterface instead. This allows
// more flexible options including different encodings.
int bsdiff(const uint8_t* old_buf, size_t oldsize, const uint8_t* new_buf,
           size_t newsize, const char* patch_filename,
           SuffixArrayIndexInterface** sai_cache) {
	BsdiffPatchWriter patch(patch_filename);
	return bsdiff(old_buf, oldsize, new_buf, newsize, 0, &patch,
	              sai_cache);
}

int bsdiff(const uint8_t* old_buf, size_t oldsize, const uint8_t* new_buf,
           size_t newsize, PatchWriterInterface* patch,
           SuffixArrayIndexInterface** sai_cache) {
	return bsdiff(old_buf, oldsize, new_buf, newsize, 0, patch,
	              sai_cache);
}

int bsdiff(const uint8_t* old_buf, size_t oldsize, const uint8_t* new_buf,
           size_t newsize, size_t min_length, PatchWriterInterface* patch,
           SuffixArrayIndexInterface** sai_cache) {
	size_t scsc, scan;
	uint64_t pos=0;
	size_t len;
	size_t lastscan,lastpos,lastoffset;
	uint64_t oldscore;
	ssize_t s,Sf,lenf,Sb,lenb;
	ssize_t overlap,Ss,lens;
	ssize_t i;

	std::unique_ptr<SuffixArrayIndexInterface> local_sai;
	SuffixArrayIndexInterface* sai;

	if (sai_cache && *sai_cache) {
		sai = *sai_cache;
	} else {
		local_sai = CreateSuffixArrayIndex(old_buf, oldsize);
		if (!local_sai)
			return 1;
		sai = local_sai.get();

		// Transfer ownership to the caller.
		if (sai_cache)
			*sai_cache = local_sai.release();
	}

	/* Initialize the patch file encoder */
	DiffEncoder diff_encoder(patch, old_buf, oldsize, new_buf, newsize);
	if (!diff_encoder.Init())
		return 1;

	/* Compute the differences, writing ctrl as we go */
	scan=0;len=0;
	lastscan=0;lastpos=0;lastoffset=0;
	while(scan<newsize) {
		oldscore=0;

		/* If we come across a large block of data that only differs
		 * by less than 8 bytes, this loop will take a long time to
		 * go past that block of data. We need to track the number of
		 * times we're stuck in the block and break out of it. */
		int num_less_than_eight = 0;
		size_t prev_len;
		uint64_t prev_pos, prev_oldscore;
		for(scsc=scan+=len;scan<newsize;scan++) {
			prev_len=len;
			prev_oldscore=oldscore;
			prev_pos=pos;

			sai->SearchPrefix(new_buf + scan, newsize - scan, &len, &pos);

			for(;scsc<scan+len && scsc+lastoffset<oldsize;scsc++)
				if(old_buf[scsc+lastoffset] == new_buf[scsc])
					oldscore++;

			if(((len==oldscore) && (len!=0)) ||
				(len>oldscore+8 && len>=min_length)) break;

			if((scan+lastoffset<oldsize) &&
				(old_buf[scan+lastoffset] == new_buf[scan]))
				oldscore--;

			const size_t fuzz = 8;
			if (prev_len-fuzz<=len && len<=prev_len &&
			    prev_oldscore-fuzz<=oldscore &&
			    oldscore<=prev_oldscore &&
			    prev_pos<=pos && pos <=prev_pos+fuzz &&
			    oldscore<=len && len<=oldscore+fuzz)
				++num_less_than_eight;
			else
				num_less_than_eight=0;
			if (num_less_than_eight > 100) break;
		};

		if((len!=oldscore) || (scan==newsize)) {
			s=0;Sf=0;lenf=0;
			for(i=0;(lastscan+i<scan)&&(lastpos+i<oldsize);) {
				if(old_buf[lastpos+i]==new_buf[lastscan+i]) s++;
				i++;
				if(s*2-i>Sf*2-lenf) { Sf=s; lenf=i; };
			};

			lenb=0;
			if(scan<newsize) {
				s=0;Sb=0;
				for(i=1;(scan>=lastscan+i)&&(pos>=static_cast<uint64_t>(i));i++) {
					if(old_buf[pos-i]==new_buf[scan-i]) s++;
					if(s*2-i>Sb*2-lenb) { Sb=s; lenb=i; };
				};
			};

			if(lastscan+lenf>scan-lenb) {
				overlap=(lastscan+lenf)-(scan-lenb);
				s=0;Ss=0;lens=0;
				for(i=0;i<overlap;i++) {
					if(new_buf[lastscan+lenf-overlap+i]==
					   old_buf[lastpos+lenf-overlap+i]) s++;
					if(new_buf[scan-lenb+i]==
					   old_buf[pos-lenb+i]) s--;
					if(s>Ss) { Ss=s; lens=i+1; };
				};

				lenf+=lens-overlap;
				lenb-=lens;
			};

			if (!diff_encoder.AddControlEntry(
			        ControlEntry(lenf,
			                     (scan - lenb) - (lastscan + lenf),
			                     (pos - lenb) - (lastpos + lenf))))
				errx(1, "Writing a control entry");

			lastscan=scan-lenb;
			lastpos=pos-lenb;
			lastoffset=pos-scan;
		};
	};
	if (!diff_encoder.Close())
		errx(1, "Closing the patch file");

	return 0;
}

}  // namespace bsdiff
