package engine

import (
	"encoding/hex"
	"fmt"
	"os"
	"path/filepath"
	"time"

	"github.com/deranjer/gvc/common/database"
)

// CreateInitialCommit copies the files over and compresses them if they are not in the NoCompress struct
func (m *Manager) CreateInitialCommit(fileList []database.File, branch string, commitMessage string) error { // ONLY HAPPENS FOR MASTER I THINK, SO NO BRANCH NEEDED
	m.Info().Msgf("Starting initial commit on branch: %s", branch)
	//Need to deduplicate so we aren't storing duplicates of files, storing all the files in one folder won't work, will need something like git
	//For initial commit no changes are made to files, so don't store anything, just save the list so you can send to server
	var initialCommit database.Commit
	initialCommit.Branch = "master"
	hashBytes, err := CreateCommitHash(fileList, commitMessage)
	if err != nil {
		return err
	}
	currentTime := time.Now()
	initialCommit.CommitHash = hashBytes
	initialCommit.Number = 1
	initialCommit.TrackedFiles = fileList
	initialCommit.Date = currentTime.String()
	folder := m.FilePaths.ObjectFolder + string(filepath.Separator) + hex.EncodeToString(hashBytes)
	err = os.Mkdir(folder, 0666)
	if err != nil {
		return fmt.Errorf("unable to create commit directory in object dir: %s err: %s", folder, err)
	}
	m.Info().Msgf("Total number of files to commit: %s", len(fileList))
	fmt.Println("Total number of files to commit: ", len(fileList))
	for _, file := range fileList {
		filename, err := ConvertFileForStorage(&file, folder)
		if err != nil {
			// TODO: roll back commit on error (folders/files created need to be deleted)
			return err
		}
		file.BaseFilePath = filename
	}
	err = m.dB.NewCommit(initialCommit, branch)
	if err != nil {
		return err
	}
	//var hashList [][]byte
	return nil

}

// CreateCommit creates a new commit by running diffs on files, compressing, etc, as needed
func (m *Manager) CreateCommit(changedFiles []database.File, trackedFiles []database.File, branch string, commitMessage string, commitNumber int) error {
	m.Info().Msgf("Starting commit number: %d on branch: %s", commitNumber, branch)
	//Need to deduplicate so we aren't storing duplicates of files, storing all the files in one folder won't work, will need something like git
	//For initial commit no changes are made to files, so don't store anything, just save the list so you can send to server
	var newCommit database.Commit
	newCommit.Branch = "master"
	hashBytes, err := CreateCommitHash(trackedFiles, commitMessage)
	if err != nil {
		return err
	}
	currentTime := time.Now()
	newCommit.CommitHash = hashBytes
	newCommit.Number = 1
	newCommit.TrackedFiles = trackedFiles
	newCommit.Date = currentTime.String()
	folder := m.FilePaths.ObjectFolder + string(filepath.Separator) + hex.EncodeToString(hashBytes)
	err = os.Mkdir(folder, 0666)
	if err != nil {
		return fmt.Errorf("unable to create commit directory in object dir: %s err: %s", folder, err)
	}
	m.Info().Msgf("Total number of files to commit: %d", len(trackedFiles))
	fmt.Println("Total number of files to commit: ", len(trackedFiles))
	// TODO: CHeck for NEW Files and convert to starage, not changed files
	for _, file := range changedFiles {
		m.Info().Msgf("Converting changed fi")
		filename, err := ConvertFileForStorage(&file, folder)
		if err != nil {
			// TODO: roll back commit on error (folders/files created need to be deleted)
			return err
		}
		file.BaseFilePath = filename
	}
	// TODO: THis needs to be the delta calculation for changed files
	err = m.dB.NewCommit(newCommit, branch)
	if err != nil {
		return err
	}
	//var hashList [][]byte
	return nil

}
