package engine

import (
	"fmt"
)

// The watcher is responsible for not only seeing when a file changes,
// but also keeping track of
// * the file hash so that if it changes again any modifications can be handled
// * copying any versions and keeping them safe (even if temporary)
// * creating the diff of the file, in both directions if necessary
// * storing the details in the database

// PatchFromFile takes the version of the file that was backed up
// and applies the specified patch to it, to get the latest file. This is incase the
// last save is the file you want to get.
func (p *Patcher) PatchFromFile(filePath, patchPath, restorePath string) error {
	if subject, err := openFile(filePath); err != nil {
		return fmt.Errorf("error on subject file: %s", err)
	} else if patch, err := openFile(patchPath); err != nil {
		return fmt.Errorf("error on patch file: %s", err)
	} else {
		return p.applyPatch(subject, patch, restorePath)
	}
}

//applyPatch actively applies the patch to the subject. This could eventually
// be upgraded for different patching algorithms
func (p *Patcher) applyPatch(subject, patch []byte, restorePath string) error {
	if delta, err := decompressDelta(patch); err != nil {
		return fmt.Errorf("error decompressing delta %s", err)
	} else {
		if appliedBytes, err := applyPatchToFile(subject, delta); err != nil {
			return fmt.Errorf("error applying delta to original file %s", err)
		} else if err := writeFile(restorePath, appliedBytes); err != nil {
			return fmt.Errorf("error writing patchedFile %s", err)
		}
		return nil
	}

}
