// 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 <string.h>

#include "gn/source_file.h"

#include "base/logging.h"
#include "gn/filesystem_utils.h"
#include "gn/source_dir.h"
#include "util/build_config.h"

namespace {

void AssertValueSourceFileString(const std::string& s) {
#if defined(OS_WIN)
  DCHECK(s[0] == '/' ||
         (s.size() > 2 && s[0] != '/' && s[1] == ':' && IsSlash(s[2])));
#else
  DCHECK(s[0] == '/');
#endif
  DCHECK(!EndsWithSlash(s)) << s;
}

bool EndsWithExtension(std::string_view str, std::string_view ext) {
  return str.size() > ext.size() && str[str.size() - ext.size() - 1] == '.' &&
         !::memcmp(str.data() + str.size() - ext.size(), ext.data(),
                   ext.size());
}

SourceFile::Type GetSourceFileType(const std::string& file) {
  size_t size = file.size();
  const char* str = file.data();

  // First, single-char extensions.
  if (size > 2 && str[size - 2] == '.') {
    switch (str[size - 1]) {
      case 'c':
        return SourceFile::SOURCE_C;  // .c
      case 'h':
        return SourceFile::SOURCE_H;  // .h
      case 'm':
        return SourceFile::SOURCE_M;  // .m
      case 'o':
        return SourceFile::SOURCE_O;  // .o
      case 'S':
      case 's':
        return SourceFile::SOURCE_S;  // .S and .s
      default:
        return SourceFile::SOURCE_UNKNOWN;
    }
  }

  // Second, two-char extensions
  if (size > 3 && str[size - 3] == '.') {
#define TAG2(c1, c2) ((unsigned)(c1) | ((unsigned)(c2) << 8))
    switch (TAG2(str[size - 2], str[size - 1])) {
      case TAG2('c', 'c'):
        return SourceFile::SOURCE_CPP;  // .cc
      case TAG2('g', 'o'):
        return SourceFile::SOURCE_GO;  // .go
      case TAG2('h', 'h'):
        return SourceFile::SOURCE_H;  // .hh
      case TAG2('m', 'm'):
        return SourceFile::SOURCE_MM;  // .mm
      case TAG2('r', 'c'):
        return SourceFile::SOURCE_RC;  // .rc
      case TAG2('r', 's'):
        return SourceFile::SOURCE_RS;  // .rs
      default:
        return SourceFile::SOURCE_UNKNOWN;
    }
#undef TAG2
  }

  if (size > 4 && str[size - 4] == '.') {
#define TAG3(c1, c2, c3) \
  ((unsigned)(c1) | ((unsigned)(c2) << 8) | ((unsigned)(c3) << 16))
    switch (TAG3(str[size - 3], str[size - 2], str[size - 1])) {
      case TAG3('c', 'p', 'p'):
      case TAG3('c', 'x', 'x'):
      case TAG3('c', '+', '+'):
        return SourceFile::SOURCE_CPP;
      case TAG3('h', 'p', 'p'):
      case TAG3('h', 'x', 'x'):
      case TAG3('i', 'n', 'c'):
      case TAG3('i', 'p', 'p'):
      case TAG3('i', 'n', 'l'):
        return SourceFile::SOURCE_H;
      case TAG3('a', 's', 'm'):
        return SourceFile::SOURCE_S;
      case TAG3('d', 'e', 'f'):
        return SourceFile::SOURCE_DEF;
      case TAG3('o', 'b', 'j'):
        return SourceFile::SOURCE_O;
      default:
        return SourceFile::SOURCE_UNKNOWN;
    }
#undef TAG3
  }

  // Other cases
  if (EndsWithExtension(file, "hpp11"))
    return SourceFile::SOURCE_H;

  if (EndsWithExtension(file, "swift"))
    return SourceFile::SOURCE_SWIFT;

  if (EndsWithExtension(file, "swiftmodule"))
    return SourceFile::SOURCE_SWIFTMODULE;

  if (EndsWithExtension(file, "modulemap"))
    return SourceFile::SOURCE_MODULEMAP;

  return SourceFile::SOURCE_UNKNOWN;
}

std::string Normalized(std::string value) {
  DCHECK(!value.empty());
  AssertValueSourceFileString(value);
  NormalizePath(&value);
  return value;
}

}  // namespace

SourceFile::SourceFile(const std::string& value)
    : SourceFile(StringAtom(Normalized(value))) {}

SourceFile::SourceFile(std::string&& value)
    : SourceFile(StringAtom(Normalized(std::move(value)))) {}

SourceFile::SourceFile(StringAtom value) : value_(value) {}

SourceFile::Type SourceFile::GetType() const {
  return GetSourceFileType(value_.str());
}

bool SourceFile::IsDefType() const {
  std::string_view v = value_.str();
  return EndsWithExtension(v, "def");
}

bool SourceFile::IsObjectType() const {
  std::string_view v = value_.str();
  return EndsWithExtension(v, "o") || EndsWithExtension(v, "obj");
}

bool SourceFile::IsModuleMapType() const {
  std::string_view v = value_.str();
  return EndsWithExtension(v, "modulemap");
}

bool SourceFile::IsSwiftType() const {
  std::string_view v = value_.str();
  return EndsWithExtension(v, "swift");
}

bool SourceFile::IsSwiftModuleType() const {
  std::string_view v = value_.str();
  return EndsWithExtension(v, "swiftmodule");
}

std::string SourceFile::GetName() const {
  if (is_null())
    return std::string();

  const std::string& value = value_.str();
  DCHECK(value.find('/') != std::string::npos);
  size_t last_slash = value.rfind('/');
  return std::string(&value[last_slash + 1], value.size() - last_slash - 1);
}

SourceDir SourceFile::GetDir() const {
  if (is_null())
    return SourceDir();

  const std::string& value = value_.str();
  DCHECK(value.find('/') != std::string::npos);
  size_t last_slash = value.rfind('/');
  return SourceDir(value.substr(0, last_slash + 1));
}

base::FilePath SourceFile::Resolve(const base::FilePath& source_root) const {
  return ResolvePath(value_.str(), true, source_root);
}

void SourceFile::SetValue(const std::string& value) {
  value_ = StringAtom(value);
}

SourceFileTypeSet::SourceFileTypeSet() : empty_(true) {
  memset(flags_, 0,
         sizeof(bool) * static_cast<int>(SourceFile::SOURCE_NUMTYPES));
}

bool SourceFileTypeSet::CSourceUsed() const {
  return empty_ || Get(SourceFile::SOURCE_CPP) ||
         Get(SourceFile::SOURCE_MODULEMAP) || Get(SourceFile::SOURCE_H) ||
         Get(SourceFile::SOURCE_C) || Get(SourceFile::SOURCE_M) ||
         Get(SourceFile::SOURCE_MM) || Get(SourceFile::SOURCE_RC) ||
         Get(SourceFile::SOURCE_S) || Get(SourceFile::SOURCE_O) ||
         Get(SourceFile::SOURCE_DEF);
}

bool SourceFileTypeSet::RustSourceUsed() const {
  return Get(SourceFile::SOURCE_RS);
}

bool SourceFileTypeSet::GoSourceUsed() const {
  return Get(SourceFile::SOURCE_GO);
}

bool SourceFileTypeSet::SwiftSourceUsed() const {
  return Get(SourceFile::SOURCE_SWIFT);
}

bool SourceFileTypeSet::MixedSourceUsed() const {
  return (1 << static_cast<int>(CSourceUsed())
            << static_cast<int>(RustSourceUsed())
            << static_cast<int>(GoSourceUsed())
            << static_cast<int>(SwiftSourceUsed())) > 2;
}
