package lockingwriter

import (
	"os"
	"time"

	"github.com/gofrs/flock"
)

// for now this package defines a writer for use with log.New(). It it intended to be used from the external ssh applications. This logger uses a file lock to allow all the various ssh applications to log to the same file.
// the correct way to do this is to send log events to a daemon
// but i'm trying to cut a corner

type LockingWriter struct {
	path string
}

const (
	fp = "/town/var/log/external.log"
	lp = "/town/var/log/log.lock"
)

func New() *LockingWriter {
	f, err := os.OpenFile(fp, os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0660)
	if err != nil && !os.IsExist(err) {
		panic(err)
	}
	f.Close()

	return &LockingWriter{
		path: fp,
	}
}

func (l *LockingWriter) Write(p []byte) (n int, err error) {
	fl := flock.New(lp)

	var locked bool
	for !locked {
		locked, err = fl.TryLock()
		if err != nil {
			return
		}
		time.Sleep(time.Second)
	}

	var f *os.File
	f, err = os.OpenFile(l.path, os.O_APPEND|os.O_WRONLY, 0660)
	if err != nil {
		return
	}

	defer f.Close()
	defer fl.Unlock()

	n, err = f.Write(p)

	if err != nil {
		panic(err)
	}

	return
	//return f.Write(p)
}
