// 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 <fstream>
#include <iostream>
#include <unordered_map>
#include <vector>

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

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 expect_output_path = false;
  bool verbose = false;

  std::vector<const char*> paths;
  const char* output_path = nullptr;

  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 if (0 == strcmp(cur_arg, "--output") ||
                 0 == strcmp(cur_arg, "-o")) {
        expect_output_path = true;
      } else {
        PrintUsage(argv[0]);
        continue_processing = false;
        return_code = 1;
      }
    } else {
      if (expect_output_path) {
        output_path = cur_arg;
        expect_output_path = false;
      } 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);
  spvtools::SetContextMessageConsumer(ctx.context, DiagnosticsMessageHandler);

  spvtools::stats::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 !=
        spvtools::stats::AggregateStats(*ctx.context, contents.data(),
                                        contents.size(), nullptr, &stats)) {
      std::cerr << "error: Failed to aggregate stats for " << path << std::endl;
      return 1;
    }
  }

  spvtools::stats::StatsAnalyzer analyzer(stats);

  std::ofstream fout;
  if (output_path) {
    fout.open(output_path);
    if (!fout.is_open()) {
      std::cerr << "error: Failed to open " << output_path << std::endl;
      return 1;
    }
  }

  std::ostream& out = fout.is_open() ? fout : 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);

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

  return 0;
}
