// Copyright (c) 2013 The Chromium 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 "tools/gn/ninja_build_writer.h"

#include <fstream>

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/process/process_handle.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "tools/gn/build_settings.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/input_file_manager.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/target.h"

#if defined(OS_WIN)
#include <windows.h>
#endif

namespace {

std::string GetSelfInvocationCommand(const BuildSettings* build_settings) {
#if defined(OS_WIN)
  wchar_t module[MAX_PATH];
  GetModuleFileName(NULL, module, MAX_PATH);
  //result = "\"" + WideToUTF8(module) + "\"";
  base::FilePath executable(module);
#elif defined(OS_MACOSX)
  // FIXME(brettw) write this on Mac!
  base::FilePath executable("gn");
#else
  base::FilePath executable =
      base::GetProcessExecutablePath(base::GetCurrentProcessHandle());
#endif

/*
  // Append the root path.
  CommandLine* cmdline = CommandLine::ForCurrentProcess();
  result += " --root=\"" + FilePathToUTF8(settings->root_path()) + "\"";
*/

  CommandLine cmdline(executable);
  cmdline.AppendSwitchPath("--root", build_settings->root_path());

  // TODO(brettw) append other parameters.

#if defined(OS_WIN)
  return WideToUTF8(cmdline.GetCommandLineString());
#else
  return cmdline.GetCommandLineString();
#endif
}

}  // namespace

NinjaBuildWriter::NinjaBuildWriter(
    const BuildSettings* build_settings,
    const std::vector<const Settings*>& all_settings,
    const std::vector<const Target*>& default_toolchain_targets,
    std::ostream& out)
    : build_settings_(build_settings),
      all_settings_(all_settings),
      default_toolchain_targets_(default_toolchain_targets),
      out_(out),
      path_output_(build_settings->build_dir(), ESCAPE_NINJA, true),
      helper_(build_settings) {
}

NinjaBuildWriter::~NinjaBuildWriter() {
}

void NinjaBuildWriter::Run() {
  WriteNinjaRules();
  WriteSubninjas();
  WritePhonyAndAllRules();
}

// static
bool NinjaBuildWriter::RunAndWriteFile(
    const BuildSettings* build_settings,
    const std::vector<const Settings*>& all_settings,
    const std::vector<const Target*>& default_toolchain_targets) {
  base::FilePath ninja_file(build_settings->GetFullPath(
      SourceFile(build_settings->build_dir().value() + "build.ninja")));
  file_util::CreateDirectory(ninja_file.DirName());

  std::ofstream file;
  file.open(FilePathToUTF8(ninja_file).c_str(),
            std::ios_base::out | std::ios_base::binary);
  if (file.fail())
    return false;

  NinjaBuildWriter gen(build_settings, all_settings,
                       default_toolchain_targets, file);
  gen.Run();
  return true;
}

void NinjaBuildWriter::WriteNinjaRules() {
  out_ << "rule gn\n";
  out_ << "  command = " << GetSelfInvocationCommand(build_settings_) << "\n";
  out_ << "  description = GN the world\n\n";

  out_ << "build build.ninja: gn";

  // Input build files.
  std::vector<SourceFile> input_files;
  g_scheduler->input_file_manager()->GetAllInputFileNames(&input_files);
  for (size_t i = 0; i < input_files.size(); i++) {
    out_ << " ";
    path_output_.WriteFile(out_, input_files[i]);
  }

  // Other files read by the build.
  std::vector<SourceFile> other_files = g_scheduler->GetGenDependencies();
  for (size_t i = 0; i < other_files.size(); i++) {
    out_ << " ";
    path_output_.WriteFile(out_, other_files[i]);
  }

  out_ << std::endl << std::endl;
}

void NinjaBuildWriter::WriteSubninjas() {
  for (size_t i = 0; i < all_settings_.size(); i++) {
    out_ << "subninja ";
    path_output_.WriteFile(out_,
                           helper_.GetNinjaFileForToolchain(all_settings_[i]));
    out_ << std::endl;
  }
  out_ << std::endl;
}

void NinjaBuildWriter::WritePhonyAndAllRules() {
  std::string all_rules;

  // Write phony rules for the default toolchain (don't do other toolchains or
  // we'll get naming conflicts).
  for (size_t i = 0; i < default_toolchain_targets_.size(); i++) {
    const Target* target = default_toolchain_targets_[i];
    if (target->output_type() == Target::NONE)
      continue;  // Nothing to generate.

    OutputFile target_file = helper_.GetTargetOutputFile(target);
    if (target_file.value() != target->label().name()) {
      out_ << "build " << target->label().name() << ": phony ";
      path_output_.WriteFile(out_, target_file);
      out_ << std::endl;
    }

    if (!all_rules.empty())
      all_rules.append(" $\n    ");
    all_rules.append(target_file.value());
  }

  if (!all_rules.empty()) {
    out_ << "\nbuild all: phony " << all_rules << std::endl;
    out_ << "default all" << std::endl;
  }
}

