//===-- lib/Semantics/program-tree.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 "flang/Semantics/program-tree.h"
#include "flang/Common/idioms.h"
#include "flang/Parser/char-block.h"
#include "flang/Semantics/scope.h"
#include "flang/Semantics/semantics.h"

namespace Fortran::semantics {

static void GetEntryStmts(
    ProgramTree &node, const parser::SpecificationPart &spec) {
  const auto &implicitPart{std::get<parser::ImplicitPart>(spec.t)};
  for (const parser::ImplicitPartStmt &stmt : implicitPart.v) {
    if (const auto *entryStmt{std::get_if<
            parser::Statement<common::Indirection<parser::EntryStmt>>>(
            &stmt.u)}) {
      node.AddEntry(entryStmt->statement.value());
    }
  }
  for (const auto &decl :
      std::get<std::list<parser::DeclarationConstruct>>(spec.t)) {
    if (const auto *entryStmt{std::get_if<
            parser::Statement<common::Indirection<parser::EntryStmt>>>(
            &decl.u)}) {
      node.AddEntry(entryStmt->statement.value());
    }
  }
}

static void GetEntryStmts(
    ProgramTree &node, const parser::ExecutionPart &exec) {
  for (const auto &epConstruct : exec.v) {
    if (const auto *entryStmt{std::get_if<
            parser::Statement<common::Indirection<parser::EntryStmt>>>(
            &epConstruct.u)}) {
      node.AddEntry(entryStmt->statement.value());
    }
  }
}

// Collects generics that define simple names that could include
// identically-named subprograms as specific procedures.
static void GetGenerics(
    ProgramTree &node, const parser::SpecificationPart &spec) {
  for (const auto &decl :
      std::get<std::list<parser::DeclarationConstruct>>(spec.t)) {
    if (const auto *spec{
            std::get_if<parser::SpecificationConstruct>(&decl.u)}) {
      if (const auto *generic{std::get_if<
              parser::Statement<common::Indirection<parser::GenericStmt>>>(
              &spec->u)}) {
        const parser::GenericStmt &genericStmt{generic->statement.value()};
        const auto &genericSpec{std::get<parser::GenericSpec>(genericStmt.t)};
        node.AddGeneric(genericSpec);
      } else if (const auto *interface{
                     std::get_if<common::Indirection<parser::InterfaceBlock>>(
                         &spec->u)}) {
        const parser::InterfaceBlock &interfaceBlock{interface->value()};
        const parser::InterfaceStmt &interfaceStmt{
            std::get<parser::Statement<parser::InterfaceStmt>>(interfaceBlock.t)
                .statement};
        const auto *genericSpec{
            std::get_if<std::optional<parser::GenericSpec>>(&interfaceStmt.u)};
        if (genericSpec && genericSpec->has_value()) {
          node.AddGeneric(**genericSpec);
        }
      }
    }
  }
}

template <typename T>
static ProgramTree BuildSubprogramTree(
    const parser::Name &name, SemanticsContext &context, const T &x) {
  const auto &spec{std::get<parser::SpecificationPart>(x.t)};
  const auto &exec{std::get<parser::ExecutionPart>(x.t)};
  const auto &subps{
      std::get<std::optional<parser::InternalSubprogramPart>>(x.t)};
  ProgramTree node{name, spec, &exec};
  GetEntryStmts(node, spec);
  GetEntryStmts(node, exec);
  GetGenerics(node, spec);
  if (subps) {
    for (const auto &subp :
        std::get<std::list<parser::InternalSubprogram>>(subps->t)) {
      common::visit(
          [&](const auto &y) {
            if (auto child{ProgramTree::Build(y.value(), context)}) {
              node.AddChild(std::move(*child));
            }
          },
          subp.u);
    }
  }
  return node;
}

static ProgramTree BuildSubprogramTree(
    const parser::Name &name, SemanticsContext &, const parser::BlockData &x) {
  const auto &spec{std::get<parser::SpecificationPart>(x.t)};
  return ProgramTree{name, spec};
}

template <typename T>
static ProgramTree BuildModuleTree(
    const parser::Name &name, SemanticsContext &context, const T &x) {
  const auto &spec{std::get<parser::SpecificationPart>(x.t)};
  const auto &subps{std::get<std::optional<parser::ModuleSubprogramPart>>(x.t)};
  ProgramTree node{name, spec};
  GetGenerics(node, spec);
  if (subps) {
    for (const auto &subp :
        std::get<std::list<parser::ModuleSubprogram>>(subps->t)) {
      common::visit(
          [&](const auto &y) {
            if (auto child{ProgramTree::Build(y.value(), context)}) {
              node.AddChild(std::move(*child));
            }
          },
          subp.u);
    }
  }
  return node;
}

ProgramTree &ProgramTree::Build(
    const parser::ProgramUnit &x, SemanticsContext &context) {
  return common::visit(
      [&](const auto &y) -> ProgramTree & {
        auto node{Build(y.value(), context)};
        CHECK(node.has_value());
        return context.SaveProgramTree(std::move(*node));
      },
      x.u);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::MainProgram &x, SemanticsContext &context) {
  const auto &stmt{
      std::get<std::optional<parser::Statement<parser::ProgramStmt>>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndProgramStmt>>(x.t)};
  static parser::Name emptyName;
  auto result{stmt
          ? BuildSubprogramTree(stmt->statement.v, context, x).set_stmt(*stmt)
          : BuildSubprogramTree(emptyName, context, x)};
  return std::move(result.set_endStmt(end));
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::FunctionSubprogram &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::FunctionStmt>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndFunctionStmt>>(x.t)};
  const auto &name{std::get<parser::Name>(stmt.statement.t)};
  const parser::LanguageBindingSpec *bindingSpec{};
  if (const auto &suffix{
          std::get<std::optional<parser::Suffix>>(stmt.statement.t)}) {
    if (const auto &binding{
            std::get<std::optional<parser::LanguageBindingSpec>>(suffix->t)}) {
      bindingSpec = &*binding;
    }
  }
  return BuildSubprogramTree(name, context, x)
      .set_stmt(stmt)
      .set_endStmt(end)
      .set_bindingSpec(bindingSpec);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::SubroutineSubprogram &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::SubroutineStmt>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndSubroutineStmt>>(x.t)};
  const auto &name{std::get<parser::Name>(stmt.statement.t)};
  const parser::LanguageBindingSpec *bindingSpec{};
  if (const auto &binding{std::get<std::optional<parser::LanguageBindingSpec>>(
          stmt.statement.t)}) {
    bindingSpec = &*binding;
  }
  return BuildSubprogramTree(name, context, x)
      .set_stmt(stmt)
      .set_endStmt(end)
      .set_bindingSpec(bindingSpec);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::SeparateModuleSubprogram &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::MpSubprogramStmt>>(x.t)};
  const auto &end{
      std::get<parser::Statement<parser::EndMpSubprogramStmt>>(x.t)};
  const auto &name{stmt.statement.v};
  return BuildSubprogramTree(name, context, x).set_stmt(stmt).set_endStmt(end);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::Module &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::ModuleStmt>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndModuleStmt>>(x.t)};
  const auto &name{stmt.statement.v};
  return BuildModuleTree(name, context, x).set_stmt(stmt).set_endStmt(end);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::Submodule &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::SubmoduleStmt>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndSubmoduleStmt>>(x.t)};
  const auto &name{std::get<parser::Name>(stmt.statement.t)};
  return BuildModuleTree(name, context, x).set_stmt(stmt).set_endStmt(end);
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::BlockData &x, SemanticsContext &context) {
  const auto &stmt{std::get<parser::Statement<parser::BlockDataStmt>>(x.t)};
  const auto &end{std::get<parser::Statement<parser::EndBlockDataStmt>>(x.t)};
  static parser::Name emptyName;
  auto result{stmt.statement.v
          ? BuildSubprogramTree(*stmt.statement.v, context, x)
          : BuildSubprogramTree(emptyName, context, x)};
  return std::move(result.set_stmt(stmt).set_endStmt(end));
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::CompilerDirective &x, SemanticsContext &context) {
  if (context.ShouldWarn(common::UsageWarning::IgnoredDirective)) {
    context.Say(x.source, "Compiler directive ignored here"_warn_en_US);
  }
  return std::nullopt;
}

std::optional<ProgramTree> ProgramTree::Build(
    const parser::OpenACCRoutineConstruct &, SemanticsContext &) {
  DIE("ProgramTree::Build() called for OpenACCRoutineConstruct");
}

const parser::ParentIdentifier &ProgramTree::GetParentId() const {
  const auto *stmt{
      std::get<const parser::Statement<parser::SubmoduleStmt> *>(stmt_)};
  return std::get<parser::ParentIdentifier>(stmt->statement.t);
}

bool ProgramTree::IsModule() const {
  auto kind{GetKind()};
  return kind == Kind::Module || kind == Kind::Submodule;
}

Symbol::Flag ProgramTree::GetSubpFlag() const {
  return GetKind() == Kind::Function ? Symbol::Flag::Function
                                     : Symbol::Flag::Subroutine;
}

bool ProgramTree::HasModulePrefix() const {
  if (std::holds_alternative<
          const parser::Statement<parser::MpSubprogramStmt> *>(stmt_)) {
    return true; // MODULE PROCEDURE foo
  }
  using ListType = std::list<parser::PrefixSpec>;
  const auto *prefixes{common::visit(
      common::visitors{
          [](const parser::Statement<parser::FunctionStmt> *x) {
            return &std::get<ListType>(x->statement.t);
          },
          [](const parser::Statement<parser::SubroutineStmt> *x) {
            return &std::get<ListType>(x->statement.t);
          },
          [](const auto *) -> const ListType * { return nullptr; },
      },
      stmt_)};
  if (prefixes) {
    for (const auto &prefix : *prefixes) {
      if (std::holds_alternative<parser::PrefixSpec::Module>(prefix.u)) {
        return true;
      }
    }
  }
  return false;
}

ProgramTree::Kind ProgramTree::GetKind() const {
  return common::visit(
      common::visitors{
          [](const parser::Statement<parser::ProgramStmt> *) {
            return Kind::Program;
          },
          [](const parser::Statement<parser::FunctionStmt> *) {
            return Kind::Function;
          },
          [](const parser::Statement<parser::SubroutineStmt> *) {
            return Kind::Subroutine;
          },
          [](const parser::Statement<parser::MpSubprogramStmt> *) {
            return Kind::MpSubprogram;
          },
          [](const parser::Statement<parser::ModuleStmt> *) {
            return Kind::Module;
          },
          [](const parser::Statement<parser::SubmoduleStmt> *) {
            return Kind::Submodule;
          },
          [](const parser::Statement<parser::BlockDataStmt> *) {
            return Kind::BlockData;
          },
      },
      stmt_);
}

void ProgramTree::set_scope(Scope &scope) {
  scope_ = &scope;
  CHECK(endStmt_);
  scope.AddSourceRange(*endStmt_);
}

void ProgramTree::AddChild(ProgramTree &&child) {
  children_.emplace_back(std::move(child));
}

void ProgramTree::AddEntry(const parser::EntryStmt &entryStmt) {
  entryStmts_.emplace_back(entryStmt);
}

void ProgramTree::AddGeneric(const parser::GenericSpec &generic) {
  genericSpecs_.emplace_back(generic);
}

} // namespace Fortran::semantics
