//===-- runtime/unit-map.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "unit-map.h"
#include "flang/Common/optional.h"

namespace Fortran::runtime::io {

void UnitMap::Initialize() {
  if (!isInitialized_) {
    freeNewUnits_.InitializeState();
    // Unit number -1 is reserved.
    // The unit numbers are pushed in reverse order so that the first
    // ones to be popped will be small and suitable for use as kind=1
    // integers.
    for (int j{freeNewUnits_.maxValue}; j > 1; --j) {
      freeNewUnits_.Add(j);
    }
    isInitialized_ = true;
  }
}

// See 12.5.6.12 in Fortran 2018.  NEWUNIT= unit numbers are negative,
// and not equal to -1 (or ERROR_UNIT, if it were negative, which it isn't.)
ExternalFileUnit &UnitMap::NewUnit(const Terminator &terminator) {
  CriticalSection critical{lock_};
  Initialize();
  Fortran::common::optional<int> n{freeNewUnits_.PopValue()};
  if (!n) {
    n = emergencyNewUnit_++;
  }
  return Create(-*n, terminator);
}

ExternalFileUnit *UnitMap::LookUpForClose(int n) {
  CriticalSection critical{lock_};
  Chain *previous{nullptr};
  int hash{Hash(n)};
  for (Chain *p{bucket_[hash].get()}; p; previous = p, p = p->next.get()) {
    if (p->unit.unitNumber() == n) {
      if (previous) {
        previous->next.swap(p->next);
      } else {
        bucket_[hash].swap(p->next);
      }
      // p->next.get() == p at this point; the next swap pushes p on closing_
      closing_.swap(p->next);
      return &p->unit;
    }
  }
  return nullptr;
}

void UnitMap::DestroyClosed(ExternalFileUnit &unit) {
  Chain *p{nullptr};
  {
    CriticalSection critical{lock_};
    Chain *previous{nullptr};
    for (p = closing_.get(); p; previous = p, p = p->next.get()) {
      if (&p->unit == &unit) {
        int n{unit.unitNumber()};
        if (n <= -2) {
          freeNewUnits_.Add(-n);
        }
        if (previous) {
          previous->next.swap(p->next);
        } else {
          closing_.swap(p->next);
        }
        break;
      }
    }
  }
  if (p) {
    p->unit.~ExternalFileUnit();
    FreeMemory(p);
  }
}

void UnitMap::CloseAll(IoErrorHandler &handler) {
  // Extract units from the map so they can be closed
  // without holding lock_.
  OwningPtr<Chain> closeList;
  {
    CriticalSection critical{lock_};
    for (int j{0}; j < buckets_; ++j) {
      while (Chain * p{bucket_[j].get()}) {
        bucket_[j].swap(p->next); // pops p from head of bucket list
        closeList.swap(p->next); // pushes p to closeList
      }
    }
  }
  while (Chain * p{closeList.get()}) {
    closeList.swap(p->next); // pops p from head of closeList
    p->unit.CloseUnit(CloseStatus::Keep, handler);
    p->unit.~ExternalFileUnit();
    FreeMemory(p);
  }
}

void UnitMap::FlushAll(IoErrorHandler &handler) {
  CriticalSection critical{lock_};
  for (int j{0}; j < buckets_; ++j) {
    for (Chain *p{bucket_[j].get()}; p; p = p->next.get()) {
      p->unit.FlushOutput(handler);
    }
  }
}

ExternalFileUnit *UnitMap::Find(const char *path, std::size_t pathLen) {
  if (path) {
    // TODO: Faster data structure
    for (int j{0}; j < buckets_; ++j) {
      for (Chain *p{bucket_[j].get()}; p; p = p->next.get()) {
        if (p->unit.path() && p->unit.pathLength() == pathLen &&
            std::memcmp(p->unit.path(), path, pathLen) == 0) {
          return &p->unit;
        }
      }
    }
  }
  return nullptr;
}

ExternalFileUnit &UnitMap::Create(int n, const Terminator &terminator) {
  Chain &chain{*New<Chain>{terminator}(n).release()};
  chain.next.reset(&chain);
  bucket_[Hash(n)].swap(chain.next); // pushes new node as list head
  return chain.unit;
}

} // namespace Fortran::runtime::io
