// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/fxl/logging.h"
#include "src/ui/lib/escher/defaults/default_shader_program_factory.h"
#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/escher_process_init.h"
#include "src/ui/lib/escher/flatland/flatland_static_config.h"
#include "src/ui/lib/escher/forward_declarations.h"
#include "src/ui/lib/escher/fs/hack_filesystem.h"
#include "src/ui/lib/escher/hmd/pose_buffer_latching_shader.h"
#include "src/ui/lib/escher/paper/paper_renderer_config.h"
#include "src/ui/lib/escher/paper/paper_renderer_static_config.h"
#include "src/ui/lib/escher/shaders/util/spirv_file_util.h"
#include "src/ui/lib/escher/vk/shader_program.h"

#include "third_party/shaderc/libshaderc/include/shaderc/shaderc.hpp"

namespace escher {

// Compiles all of the provided shader modules and writes out their spirv
// to disk in the source tree.
bool CompileAndWriteShader(HackFilesystemPtr filesystem, ShaderProgramData program_data) {
  std::string abs_root = *filesystem->base_path() + "/shaders/spirv/";

  static auto compiler = std::make_unique<shaderc::Compiler>();

  // Loop over all the shader stages.
  for (const auto& iter : program_data.source_files) {
    // Skip if path is empty.
    if (iter.second.length() == 0) {
      continue;
    }

    FX_LOGS(INFO) << "Processing shader " << iter.second;

    auto shader = fxl::MakeRefCounted<ShaderModuleTemplate>(vk::Device(), compiler.get(),
                                                            iter.first, iter.second, filesystem);

    std::vector<uint32_t> spirv;
    if (!shader->CompileVariantToSpirv(program_data.args, &spirv)) {
      FX_LOGS(ERROR) << "could not compile shader " << iter.second;
      return false;
    }

    // As per above, only write out the spirv if there has been a change.
    if (shader_util::SpirvExistsOnDisk(program_data.args, abs_root, iter.second, spirv)) {
      if (!shader_util::WriteSpirvToDisk(spirv, program_data.args, abs_root, iter.second)) {
        FX_LOGS(ERROR) << "could not write shader " << iter.second << " to disk.";
        return false;
      }
    } else {
      FX_LOGS(INFO) << "Shader already exists on disk.";
    }
  }
  return true;
}

}  // namespace escher

int main(int argc, const char** argv) {
  // Register all the shader files, along with include files, that are used by Escher.
  auto filesystem = escher::HackFilesystem::New();

  // The binary for this is expected to be in ./out/default/host_x64.

  auto paths = escher::kPaperRendererShaderPaths;
  paths.insert(paths.end(), escher::kFlatlandShaderPaths.begin(),
               escher::kFlatlandShaderPaths.end());
  paths.insert(paths.end(), escher::hmd::kPoseBufferLatchingPaths.begin(),
               escher::hmd::kPoseBufferLatchingPaths.end());
  bool success = filesystem->InitializeWithRealFiles(paths, "./../../../../src/ui/lib/escher/");
  FX_CHECK(success);
  FX_CHECK(filesystem->base_path());

  // Ambient light program.
  if (!CompileAndWriteShader(filesystem, escher::kAmbientLightProgramData)) {
    return EXIT_FAILURE;
  }

  // No lighting program.
  if (!CompileAndWriteShader(filesystem, escher::kNoLightingProgramData)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, escher::kPointLightProgramData)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, escher::kPointLightFalloffProgramData)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, escher::kShadowVolumeGeometryProgramData)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, escher::kShadowVolumeGeometryDebugProgramData)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, escher::hmd::kPoseBufferLatchingProgramData)) {
    return EXIT_FAILURE;
  }

  // Flatland shader.
  if (!CompileAndWriteShader(filesystem, escher::kFlatlandStandardProgram)) {
    return EXIT_FAILURE;
  }

  // Test shaders from escher/test/vk/shader_program_unittest.cc
  const escher::ShaderProgramData test_variant1 = {
      .source_files = {{escher::ShaderStage::kVertex, "shaders/model_renderer/main.vert"},
                       {escher::ShaderStage::kFragment, "shaders/model_renderer/main.frag"}},
      .args = escher::ShaderVariantArgs({{"USE_ATTRIBUTE_UV", "1"},
                                         {"USE_PAPER_SHADER_PUSH_CONSTANTS", "1"},
                                         {"NO_SHADOW_LIGHTING_PASS", "1"}}),
  };
  const escher::ShaderProgramData test_variant2 = {
      .source_files = {{escher::ShaderStage::kVertex, "shaders/model_renderer/main.vert"},
                       {escher::ShaderStage::kFragment, "shaders/model_renderer/main.frag"}},
      .args = escher::ShaderVariantArgs({{"USE_ATTRIBUTE_UV", "0"},
                                         {"USE_PAPER_SHADER_PUSH_CONSTANTS", "1"},
                                         {"NO_SHADOW_LIGHTING_PASS", "1"}}),
  };

  if (!CompileAndWriteShader(filesystem, test_variant1)) {
    return EXIT_FAILURE;
  }

  if (!CompileAndWriteShader(filesystem, test_variant2)) {
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}
