/*
 * Copyright 2018 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.
 */

//
// Similar to strip-ing a native binary, this family of passes can
// removes debug info and other things.
//

#include <functional>

#include "pass.h"
#include "wasm-binary.h"
#include "wasm.h"

namespace wasm {

struct Strip : public Pass {
  bool requiresNonNullableLocalFixups() override { return false; }

  // A function that returns true if the method should be removed.
  typedef std::function<bool(UserSection&)> Decider;
  Decider decider;

  Strip(Decider decider) : decider(decider) {}

  void run(PassRunner* runner, Module* module) override {
    // Remove name and debug sections.
    auto& sections = module->userSections;
    sections.erase(std::remove_if(sections.begin(), sections.end(), decider),
                   sections.end());
    // If we're cleaning up debug info, clear on the function and module too.
    UserSection temp;
    temp.name = BinaryConsts::UserSections::Name;
    if (decider(temp)) {
      module->clearDebugInfo();
      for (auto& func : module->functions) {
        func->clearNames();
        func->clearDebugInfo();
      }
    }
  }
};

Pass* createStripDebugPass() {
  return new Strip([&](const UserSection& curr) {
    return curr.name == BinaryConsts::UserSections::Name ||
           curr.name == BinaryConsts::UserSections::SourceMapUrl ||
           curr.name.find(".debug") == 0 || curr.name.find("reloc..debug") == 0;
  });
}

Pass* createStripDWARFPass() {
  return new Strip([&](const UserSection& curr) {
    return curr.name.find(".debug") == 0 || curr.name.find("reloc..debug") == 0;
  });
}

Pass* createStripProducersPass() {
  return new Strip([&](const UserSection& curr) {
    return curr.name == BinaryConsts::UserSections::Producers;
  });
}

} // namespace wasm
