// Copyright (c) 2012 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 "base/sys_info.h"

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/lazy_instance.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/string_tokenizer.h"
#include "base/threading/thread_restrictions.h"

#include <execinfo.h>

namespace base {

static const char* kLinuxStandardBaseVersionKeys[] = {
  "CHROMEOS_RELEASE_VERSION",
  "GOOGLE_RELEASE",
  "DISTRIB_RELEASE",
  NULL
};

const char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release";

struct ChromeOSVersionNumbers {
  ChromeOSVersionNumbers()
      : major_version(0),
        minor_version(0),
        bugfix_version(0),
        parsed(false) {
  }

  int32 major_version;
  int32 minor_version;
  int32 bugfix_version;
  bool parsed;
};

static base::LazyInstance<ChromeOSVersionNumbers>
    g_chrome_os_version_numbers = LAZY_INSTANCE_INITIALIZER;

// static
void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
                                            int32* minor_version,
                                            int32* bugfix_version) {
  if (!g_chrome_os_version_numbers.Get().parsed) {
    // The other implementations of SysInfo don't block on the disk.
    // See http://code.google.com/p/chromium/issues/detail?id=60394
    // Perhaps the caller ought to cache this?
    // Temporary allowing while we work the bug out.
    base::ThreadRestrictions::ScopedAllowIO allow_io;

    FilePath path(kLinuxStandardBaseReleaseFile);
    std::string contents;
    if (file_util::ReadFileToString(path, &contents)) {
      g_chrome_os_version_numbers.Get().parsed = true;
      ParseLsbRelease(contents,
          &(g_chrome_os_version_numbers.Get().major_version),
          &(g_chrome_os_version_numbers.Get().minor_version),
          &(g_chrome_os_version_numbers.Get().bugfix_version));
    }
  }
  *major_version = g_chrome_os_version_numbers.Get().major_version;
  *minor_version = g_chrome_os_version_numbers.Get().minor_version;
  *bugfix_version = g_chrome_os_version_numbers.Get().bugfix_version;
}

// static
std::string SysInfo::GetLinuxStandardBaseVersionKey() {
  return std::string(kLinuxStandardBaseVersionKeys[0]);
}

// static
void SysInfo::ParseLsbRelease(const std::string& lsb_release,
                              int32* major_version,
                              int32* minor_version,
                              int32* bugfix_version) {
  size_t version_key_index = std::string::npos;
  for (int i = 0; kLinuxStandardBaseVersionKeys[i] != NULL; ++i) {
    version_key_index = lsb_release.find(kLinuxStandardBaseVersionKeys[i]);
    if (std::string::npos != version_key_index) {
      break;
    }
  }
  if (std::string::npos == version_key_index) {
    return;
  }

  size_t start_index = lsb_release.find_first_of('=', version_key_index);
  start_index++;  // Move past '='.
  size_t length = lsb_release.find_first_of('\n', start_index) - start_index;
  std::string version = lsb_release.substr(start_index, length);
  StringTokenizer tokenizer(version, ".");
  for (int i = 0; i < 3 && tokenizer.GetNext(); ++i) {
    if (0 == i) {
      StringToInt(StringPiece(tokenizer.token_begin(),
                              tokenizer.token_end()),
                  major_version);
      *minor_version = *bugfix_version = 0;
    } else if (1 == i) {
      StringToInt(StringPiece(tokenizer.token_begin(),
                              tokenizer.token_end()),
                  minor_version);
    } else {  // 2 == i
      StringToInt(StringPiece(tokenizer.token_begin(),
                              tokenizer.token_end()),
                  bugfix_version);
    }
  }
}

// static
FilePath SysInfo::GetLsbReleaseFilePath() {
  return FilePath(kLinuxStandardBaseReleaseFile);
}

}  // namespace base
