/*
 * Copyright 2023 WebAssembly Community Group participants
 *
 * 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.
 */

#include "contexts.h"

namespace wasm::WATParser {

namespace {

void applyImportNames(Importable& item, ImportNames* names) {
  if (names) {
    item.module = names->mod;
    item.base = names->nm;
  }
}

Result<> addExports(Lexer& in,
                    Module& wasm,
                    const Named* item,
                    const std::vector<Name>& exports,
                    ExternalKind kind) {
  for (auto name : exports) {
    if (wasm.getExportOrNull(name)) {
      // TODO: Fix error location
      return in.err("repeated export name");
    }
    wasm.addExport(Builder(wasm).makeExport(name, item->name, kind));
  }
  return Ok{};
}

} // anonymous namespace

Result<Function*>
ParseDeclsCtx::addFuncDecl(Index pos, Name name, ImportNames* importNames) {
  auto f = std::make_unique<Function>();
  if (name.is()) {
    if (wasm.getFunctionOrNull(name)) {
      // TDOO: if the existing function is not explicitly named, fix its name
      // and continue.
      return in.err(pos, "repeated function name");
    }
    f->setExplicitName(name);
  } else {
    name = (importNames ? "fimport$" : "") + std::to_string(funcCounter++);
    name = Names::getValidFunctionName(wasm, name);
    f->name = name;
  }
  applyImportNames(*f, importNames);
  return wasm.addFunction(std::move(f));
}

Result<> ParseDeclsCtx::addFunc(Name name,
                                const std::vector<Name>& exports,
                                ImportNames* import,
                                TypeUseT type,
                                Exactness exact,
                                std::optional<LocalsT>,
                                std::vector<Annotation>&& annotations,
                                Index pos) {
  CHECK_ERR(checkImport(pos, import));
  auto f = addFuncDecl(pos, name, import);
  CHECK_ERR(f);
  CHECK_ERR(addExports(in, wasm, *f, exports, ExternalKind::Function));
  funcDefs.push_back(
    {name, pos, Index(funcDefs.size()), std::move(annotations)});
  return Ok{};
}

Result<Table*> ParseDeclsCtx::addTableDecl(Index pos,
                                           Name name,
                                           ImportNames* importNames,
                                           TableType type) {
  auto t = std::make_unique<Table>();
  t->addressType = type.addressType;
  t->initial = type.limits.initial;
  t->max = type.limits.max ? *type.limits.max : Table::kUnlimitedSize;
  if (name.is()) {
    if (wasm.getTableOrNull(name)) {
      // TODO: if the existing table is not explicitly named, fix its name and
      // continue.
      return in.err(pos, "repeated table name");
    }
    t->setExplicitName(name);
  } else {
    name = (importNames ? "timport$" : "") + std::to_string(tableCounter++);
    name = Names::getValidTableName(wasm, name);
    t->name = name;
  }
  applyImportNames(*t, importNames);
  return wasm.addTable(std::move(t));
}

Result<> ParseDeclsCtx::addTable(Name name,
                                 const std::vector<Name>& exports,
                                 ImportNames* import,
                                 TableType type,
                                 Index pos) {
  CHECK_ERR(checkImport(pos, import));
  auto t = addTableDecl(pos, name, import, type);
  CHECK_ERR(t);
  CHECK_ERR(addExports(in, wasm, *t, exports, ExternalKind::Table));
  // TODO: table annotations
  tableDefs.push_back({name, pos, Index(tableDefs.size()), {}});
  return Ok{};
}

Result<> ParseDeclsCtx::addImplicitElems(TypeT, ElemListT&& elems) {
  auto& table = *wasm.tables.back();
  auto e = std::make_unique<ElementSegment>();
  e->table = table.name;
  e->offset = Builder(wasm).makeConstPtr(0, Type::i32);
  e->name = Names::getValidElementSegmentName(wasm, "implicit-elem");
  wasm.addElementSegment(std::move(e));

  // Record the index mapping so we can find this segment again to set its type
  // and elements in later phases.
  Index tableIndex = wasm.tables.size() - 1;
  Index elemIndex = wasm.elementSegments.size() - 1;
  implicitElemIndices[tableIndex] = elemIndex;

  return Ok{};
}

Result<Memory*> ParseDeclsCtx::addMemoryDecl(Index pos,
                                             Name name,
                                             ImportNames* importNames,
                                             MemType type) {
  auto m = std::make_unique<Memory>();
  m->addressType = type.addressType;
  m->initial = type.limits.initial;
  m->max = type.limits.max ? *type.limits.max : Memory::kUnlimitedSize;
  m->shared = type.shared;
  if (name) {
    // TODO: if the existing memory is not explicitly named, fix its name
    // and continue.
    if (wasm.getMemoryOrNull(name)) {
      return in.err(pos, "repeated memory name");
    }
    m->setExplicitName(name);
  } else {
    name = (importNames ? "mimport$" : "") + std::to_string(memoryCounter++);
    name = Names::getValidMemoryName(wasm, name);
    m->name = name;
  }
  applyImportNames(*m, importNames);
  return wasm.addMemory(std::move(m));
}

Result<> ParseDeclsCtx::addMemory(Name name,
                                  const std::vector<Name>& exports,
                                  ImportNames* import,
                                  MemType type,
                                  Index pos) {
  CHECK_ERR(checkImport(pos, import));
  auto m = addMemoryDecl(pos, name, import, type);
  CHECK_ERR(m);
  CHECK_ERR(addExports(in, wasm, *m, exports, ExternalKind::Memory));
  // TODO: memory annotations
  memoryDefs.push_back({name, pos, Index(memoryDefs.size()), {}});
  return Ok{};
}

Result<> ParseDeclsCtx::addImplicitData(DataStringT&& data) {
  auto& mem = *wasm.memories.back();
  auto d = std::make_unique<DataSegment>();
  d->memory = mem.name;
  d->isPassive = false;
  d->offset = Builder(wasm).makeConstPtr(0, mem.addressType);
  d->data = std::move(data);
  d->name = Names::getValidDataSegmentName(wasm, "implicit-data");
  wasm.addDataSegment(std::move(d));
  return Ok{};
}

Result<Global*>
ParseDeclsCtx::addGlobalDecl(Index pos, Name name, ImportNames* importNames) {
  auto g = std::make_unique<Global>();
  if (name) {
    if (wasm.getGlobalOrNull(name)) {
      // TODO: if the existing global is not explicitly named, fix its name
      // and continue.
      return in.err(pos, "repeated global name");
    }
    g->setExplicitName(name);
  } else {
    name =
      (importNames ? "gimport$" : "global$") + std::to_string(globalCounter++);
    name = Names::getValidGlobalName(wasm, name);
    g->name = name;
  }
  applyImportNames(*g, importNames);
  return wasm.addGlobal(std::move(g));
}

Result<> ParseDeclsCtx::addGlobal(Name name,
                                  const std::vector<Name>& exports,
                                  ImportNames* import,
                                  GlobalTypeT,
                                  std::optional<ExprT>,
                                  Index pos) {
  CHECK_ERR(checkImport(pos, import));
  auto g = addGlobalDecl(pos, name, import);
  CHECK_ERR(g);
  CHECK_ERR(addExports(in, wasm, *g, exports, ExternalKind::Global));
  // TODO: global annotations
  globalDefs.push_back({name, pos, Index(globalDefs.size()), {}});
  return Ok{};
}

Result<> ParseDeclsCtx::addElem(
  Name name, TableIdxT*, std::optional<ExprT>, ElemListT&&, Index pos) {
  auto e = std::make_unique<ElementSegment>();
  if (name) {
    if (wasm.getElementSegmentOrNull(name)) {
      // TDOO: if the existing segment is not explicitly named, fix its name and
      // continue.
      return in.err(pos, "repeated element segment name");
    }
    e->setExplicitName(name);
  } else {
    name = std::to_string(elemCounter++);
    name = Names::getValidElementSegmentName(wasm, name);
    e->name = name;
  }
  // TODO: element segment annotations
  elemDefs.push_back({name, pos, Index(wasm.elementSegments.size()), {}});
  wasm.addElementSegment(std::move(e));
  return Ok{};
}

Result<> ParseDeclsCtx::addData(Name name,
                                MemoryIdxT*,
                                std::optional<ExprT>,
                                std::vector<char>&& data,
                                Index pos) {
  auto d = std::make_unique<DataSegment>();
  if (name) {
    if (wasm.getDataSegmentOrNull(name)) {
      // TODO: if the existing segment is not explicitly named, fix its name
      // and continue.
      return in.err(pos, "repeated data segment name");
    }
    d->setExplicitName(name);
  } else {
    name = std::to_string(dataCounter++);
    name = Names::getValidDataSegmentName(wasm, name);
    d->name = name;
  }
  d->data = std::move(data);
  // TODO: data segment annotations
  dataDefs.push_back({name, pos, Index(wasm.dataSegments.size()), {}});
  wasm.addDataSegment(std::move(d));
  return Ok{};
}

Result<Tag*>
ParseDeclsCtx::addTagDecl(Index pos, Name name, ImportNames* importNames) {
  auto t = std::make_unique<Tag>();
  if (name) {
    if (wasm.getTagOrNull(name)) {
      // TODO: if the existing tag is not explicitly named, fix its name and
      // continue.
      return in.err(pos, "repeated tag name");
    }
    t->setExplicitName(name);
  } else {
    name = (importNames ? "eimport$" : "tag$") + std::to_string(tagCounter++);
    name = Names::getValidTagName(wasm, name);
    t->name = name;
  }
  applyImportNames(*t, importNames);
  return wasm.addTag(std::move(t));
}

Result<> ParseDeclsCtx::addTag(Name name,
                               const std::vector<Name>& exports,
                               ImportNames* import,
                               TypeUseT type,
                               Index pos) {
  CHECK_ERR(checkImport(pos, import));
  auto t = addTagDecl(pos, name, import);
  CHECK_ERR(t);
  CHECK_ERR(addExports(in, wasm, *t, exports, ExternalKind::Tag));
  // TODO: tag annotations
  tagDefs.push_back({name, pos, Index(tagDefs.size()), {}});
  return Ok{};
}

} // namespace wasm::WATParser
