// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package build

import (
	"errors"
	"fmt"
	"math"
	"os"
	"path/filepath"
	"syscall"
	"time"

	"android/soong/ui/logger"
)

// This file provides cross-process synchronization methods
// i.e. making sure only one Soong process is running for a given output directory

func BecomeSingletonOrFail(ctx Context, config Config) (lock *fileLock) {
	lockingInfo, err := newLock(config.OutDir())
	if err != nil {
		ctx.Logger.Fatal(err)
	}
	lockfilePollDuration := time.Second
	lockfileTimeout := time.Second * 10
	if envTimeout := os.Getenv("SOONG_LOCK_TIMEOUT"); envTimeout != "" {
		lockfileTimeout, err = time.ParseDuration(envTimeout)
		if err != nil {
			ctx.Logger.Fatalf("failure parsing SOONG_LOCK_TIMEOUT %q: %s", envTimeout, err)
		}
	}
	err = lockSynchronous(*lockingInfo, newSleepWaiter(lockfilePollDuration, lockfileTimeout), ctx.Logger)
	if err != nil {
		ctx.Logger.Fatal(err)
	}
	return lockingInfo
}

type lockable interface {
	tryLock() error
	Unlock() error
	description() string
}

var _ lockable = (*fileLock)(nil)

type fileLock struct {
	File *os.File
}

func (l fileLock) description() (path string) {
	return l.File.Name()
}
func (l fileLock) tryLock() (err error) {
	return syscall.Flock(int(l.File.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
}
func (l fileLock) Unlock() (err error) {
	return l.File.Close()
}

func lockSynchronous(lock lockable, waiter waiter, logger logger.Logger) (err error) {

	waited := false

	for {
		err = lock.tryLock()
		if err == nil {
			if waited {
				// If we had to wait at all, then when the wait is done, we inform the user
				logger.Printf("Acquired lock on %v; previous Soong process must have completed. Continuing...\n", lock.description())
			}
			return nil
		}

		done, description := waiter.checkDeadline()

		if !waited {
			logger.Printf("Waiting up to %s to lock %v to ensure no other Soong process is running in the same output directory\n", description, lock.description())
		}

		waited = true

		if done {
			return fmt.Errorf("Tried to lock %s, but timed out %s . Make sure no other Soong process is using it",
				lock.description(), waiter.summarize())
		} else {
			waiter.wait()
		}
	}
}

func newLock(basedir string) (lock *fileLock, err error) {
	lockPath := filepath.Join(basedir, ".lock")

	os.MkdirAll(basedir, 0777)
	lockfileDescriptor, err := os.OpenFile(lockPath, os.O_RDWR|os.O_CREATE, 0666)
	if err != nil {
		return nil, errors.New("failed to open " + lockPath)
	}
	lockingInfo := &fileLock{File: lockfileDescriptor}

	return lockingInfo, nil
}

type waiter interface {
	wait()
	checkDeadline() (done bool, remainder string)
	summarize() (summary string)
}

type sleepWaiter struct {
	sleepInterval time.Duration
	deadline      time.Time

	totalWait time.Duration
}

var _ waiter = (*sleepWaiter)(nil)

func newSleepWaiter(interval time.Duration, duration time.Duration) (waiter *sleepWaiter) {
	return &sleepWaiter{interval, time.Now().Add(duration), duration}
}

func (s sleepWaiter) wait() {
	time.Sleep(s.sleepInterval)
}
func (s *sleepWaiter) checkDeadline() (done bool, remainder string) {
	remainingSleep := s.deadline.Sub(time.Now())
	numSecondsRounded := math.Floor(remainingSleep.Seconds()*10+0.5) / 10
	if remainingSleep > 0 {
		return false, fmt.Sprintf("%vs", numSecondsRounded)
	} else {
		return true, ""
	}
}
func (s sleepWaiter) summarize() (summary string) {
	return fmt.Sprintf("polling every %v until %v", s.sleepInterval, s.totalWait)
}
