// Copyright (c) 2017 Google Inc.
//
// 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 <cassert>
#include <cstring>
#include <iostream>
#include <unordered_map>

#include "source/spirv_stats.h"
#include "source/table.h"
#include "spirv-tools/libspirv.h"
#include "stats_analyzer.h"
#include "tools/io.h"

using libspirv::SpirvStats;

namespace {

struct ScopedContext {
  ScopedContext(spv_target_env env) : context(spvContextCreate(env)) {}
  ~ScopedContext() { spvContextDestroy(context); }
  spv_context context;
};

void PrintUsage(char* argv0) {
  printf(
      R"(%s - Collect statistics from one or more SPIR-V binary file(s).

USAGE: %s [options] [<filepaths>]

TIP: In order to collect statistics from all .spv files under current dir use
find . -name "*.spv" -print0 | xargs -0 -s 2000000 %s

Options:
  -h, --help                       Print this help.
  -v, --verbose                    Print additional info to stderr.
)",
      argv0, argv0, argv0);
}

void DiagnosticsMessageHandler(spv_message_level_t level, const char*,
                               const spv_position_t& position,
                               const char* message) {
  switch (level) {
    case SPV_MSG_FATAL:
    case SPV_MSG_INTERNAL_ERROR:
    case SPV_MSG_ERROR:
      std::cerr << "error: " << position.index << ": " << message
                << std::endl;
      break;
    case SPV_MSG_WARNING:
      std::cout << "warning: " << position.index << ": " << message
                << std::endl;
      break;
    case SPV_MSG_INFO:
      std::cout << "info: " << position.index << ": " << message << std::endl;
      break;
    default:
      break;
  }
}

}  // namespace

int main(int argc, char** argv) {
  bool continue_processing = true;
  int return_code = 0;

  bool verbose = false;

  std::vector<const char*> paths;

  for (int argi = 1; continue_processing && argi < argc; ++argi) {
    const char* cur_arg = argv[argi];
    if ('-' == cur_arg[0]) {
      if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) {
        PrintUsage(argv[0]);
        continue_processing = false;
        return_code = 0;
      } else if (0 == strcmp(cur_arg, "--verbose") || 0 == strcmp(cur_arg, "-v")) {
        verbose = true;
      } else {
        PrintUsage(argv[0]);
        continue_processing = false;
        return_code = 1;
      }
    } else {
      paths.push_back(cur_arg);
    }
  }

  // Exit if command line parsing was not successful.
  if (!continue_processing) {
    return return_code;
  }

  std::cerr << "Processing " << paths.size() << " files..." << std::endl;

  ScopedContext ctx(SPV_ENV_UNIVERSAL_1_1);
  SetContextMessageConsumer(ctx.context, DiagnosticsMessageHandler);

  libspirv::SpirvStats stats;
  stats.opcode_markov_hist.resize(1);

  for (size_t index = 0; index < paths.size(); ++index) {
    const size_t kMilestonePeriod = 1000;
    if (verbose) {
      if (index % kMilestonePeriod == kMilestonePeriod - 1)
        std::cerr << "Processed " << index + 1 << " files..." << std::endl;
    }

    const char* path = paths[index];
    std::vector<uint32_t> contents;
    if (!ReadFile<uint32_t>(path, "rb", &contents)) return 1;

    if (SPV_SUCCESS != libspirv::AggregateStats(
        *ctx.context, contents.data(), contents.size(), nullptr, &stats)) {
      std::cerr << "error: Failed to aggregate stats for " << path << std::endl;
      return 1;
    }
  }

  StatsAnalyzer analyzer(stats);

  std::ostream& out = std::cout;

  out << std::endl;
  analyzer.WriteVersion(out);
  analyzer.WriteGenerator(out);

  out << std::endl;
  analyzer.WriteCapability(out);

  out << std::endl;
  analyzer.WriteExtension(out);

  out << std::endl;
  analyzer.WriteOpcode(out);

  out << std::endl;
  analyzer.WriteOpcodeMarkov(out);

  return 0;
}
