/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2014 Ruslan Baratov

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmFileLockPool.h"

#include <assert.h>

#include "cmFileLock.h"
#include "cmFileLockResult.h"

cmFileLockPool::cmFileLockPool()
{
}

cmFileLockPool::~cmFileLockPool()
{
  cmDeleteAll(this->FunctionScopes);
  cmDeleteAll(this->FileScopes);
}

void cmFileLockPool::PushFunctionScope()
{
  this->FunctionScopes.push_back(new ScopePool());
}

void cmFileLockPool::PopFunctionScope()
{
  assert(!this->FunctionScopes.empty());
  delete this->FunctionScopes.back();
  this->FunctionScopes.pop_back();
}

void cmFileLockPool::PushFileScope()
{
  this->FileScopes.push_back(new ScopePool());
}

void cmFileLockPool::PopFileScope()
{
  assert(!this->FileScopes.empty());
  delete this->FileScopes.back();
  this->FileScopes.pop_back();
}

cmFileLockResult cmFileLockPool::LockFunctionScope(
    const std::string& filename, unsigned long timeoutSec)
{
  if (this->IsAlreadyLocked(filename))
    {
    return cmFileLockResult::MakeAlreadyLocked();
    }
  if (this->FunctionScopes.empty())
    {
    return cmFileLockResult::MakeNoFunction();
    }
  return this->FunctionScopes.back()->Lock(filename, timeoutSec);
}

cmFileLockResult cmFileLockPool::LockFileScope(
    const std::string& filename, unsigned long timeoutSec)
{
  if (this->IsAlreadyLocked(filename))
    {
    return cmFileLockResult::MakeAlreadyLocked();
    }
  assert(!this->FileScopes.empty());
  return this->FileScopes.back()->Lock(filename, timeoutSec);
}

cmFileLockResult cmFileLockPool::LockProcessScope(
    const std::string& filename, unsigned long timeoutSec)
{
  if (this->IsAlreadyLocked(filename))
    {
    return cmFileLockResult::MakeAlreadyLocked();
    }
  return this->ProcessScope.Lock(filename, timeoutSec);
}

cmFileLockResult cmFileLockPool::Release(const std::string& filename)
{
  for (It i = this->FunctionScopes.begin();
      i != this->FunctionScopes.end(); ++i)
    {
    const cmFileLockResult result = (*i)->Release(filename);
    if (!result.IsOk())
      {
      return result;
      }
    }

  for (It i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i)
    {
    const cmFileLockResult result = (*i)->Release(filename);
    if (!result.IsOk())
      {
      return result;
      }
    }

  return this->ProcessScope.Release(filename);
}

bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
{
  for (CIt i = this->FunctionScopes.begin();
      i != this->FunctionScopes.end(); ++i)
    {
    const bool result = (*i)->IsAlreadyLocked(filename);
    if (result)
      {
      return true;
      }
    }

  for (CIt i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i)
    {
    const bool result = (*i)->IsAlreadyLocked(filename);
    if (result)
      {
      return true;
      }
    }

  return this->ProcessScope.IsAlreadyLocked(filename);
}

cmFileLockPool::ScopePool::ScopePool()
{
}

cmFileLockPool::ScopePool::~ScopePool()
{
  cmDeleteAll(this->Locks);
}

cmFileLockResult cmFileLockPool::ScopePool::Lock(
    const std::string& filename, unsigned long timeoutSec)
{
  cmFileLock *lock = new cmFileLock();
  const cmFileLockResult result = lock->Lock(filename, timeoutSec);
  if (result.IsOk())
    {
    this->Locks.push_back(lock);
    return cmFileLockResult::MakeOk();
    }
  else
    {
    delete lock;
    return result;
    }
}

cmFileLockResult cmFileLockPool::ScopePool::Release(
    const std::string& filename)
{
  for (It i = this->Locks.begin(); i != this->Locks.end(); ++i)
    {
    if ((*i)->IsLocked(filename))
      {
      return (*i)->Release();
      }
    }
  return cmFileLockResult::MakeOk();
}

bool cmFileLockPool::ScopePool::IsAlreadyLocked(
    const std::string& filename) const
{
  for (CIt i = this->Locks.begin(); i != this->Locks.end(); ++i)
    {
    if ((*i)->IsLocked(filename))
      {
      return true;
      }
    }
  return false;
}
