// Copyright (c) 2013 The Chromium OS 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 "shill/certificate_file.h"

#include <sys/stat.h>

#include <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "shill/logging.h"

using base::FilePath;
using base::SplitString;
using base::StringPrintf;
using std::string;
using std::vector;

namespace shill {

const char CertificateFile::kDefaultRootDirectory[] =
    RUNDIR "/certificate_export";
const char CertificateFile::kPEMHeader[] = "-----BEGIN CERTIFICATE-----";
const char CertificateFile::kPEMFooter[] = "-----END CERTIFICATE-----";

CertificateFile::CertificateFile()
    : root_directory_(FilePath(kDefaultRootDirectory)) {
  SLOG(Crypto, 2) << __func__;
}

CertificateFile::~CertificateFile() {
  SLOG(Crypto, 2) << __func__;
  if (!output_file_.empty()) {
    base::DeleteFile(output_file_, false);
  }
}

FilePath CertificateFile::CreatePEMFromStrings(
    const vector<string> &pem_contents) {
  vector<string> pem_output;
  for (const auto &content : pem_contents) {
    string hex_data = ExtractHexData(content);
    if (hex_data.empty()) {
      return FilePath();
    }
    pem_output.push_back(StringPrintf(
      "%s\n%s%s\n", kPEMHeader, hex_data.c_str(), kPEMFooter));
  }
  return WriteFile(JoinString(pem_output, ""));
}

// static
string CertificateFile::ExtractHexData(const std::string &pem_data) {
  bool found_header = false;
  bool found_footer = false;
  const bool kCaseSensitive = false;
  vector<string> input_lines;
  SplitString(pem_data, '\n', &input_lines);
  vector<string> output_lines;
  for (vector<string>::const_iterator it = input_lines.begin();
       it != input_lines.end(); ++it) {
    string line;
    base::TrimWhitespaceASCII(*it, base::TRIM_ALL, &line);
    if (StartsWithASCII(line, kPEMHeader, kCaseSensitive)) {
      if (found_header) {
        LOG(ERROR) << "Found two PEM headers in a row.";
        return string();
      } else {
        found_header = true;
        output_lines.clear();
      }
    } else if (StartsWithASCII(line, kPEMFooter, kCaseSensitive)) {
      if (!found_header) {
        LOG(ERROR) << "Found a PEM footer before header.";
        return string();
      } else {
        found_footer = true;
        break;
      }
    } else if (!line.empty()) {
      output_lines.push_back(line);
    }
  }
  if (found_header && !found_footer) {
    LOG(ERROR) << "Found PEM header but no footer.";
    return string();
  }
  DCHECK_EQ(found_header, found_footer);
  output_lines.push_back("");
  return JoinString(output_lines, "\n");
}

FilePath CertificateFile::WriteFile(const string &output_data) {
  if (!base::DirectoryExists(root_directory_)) {
    if (!base::CreateDirectory(root_directory_)) {
      LOG(ERROR) << "Unable to create parent directory  "
                 << root_directory_.value();
      return FilePath();
    }
    if (chmod(root_directory_.value().c_str(),
              S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH)) {
      LOG(ERROR) << "Failed to set permissions on "
                 << root_directory_.value();
      base::DeleteFile(root_directory_, true);
      return FilePath();
    }
  }
  if (!output_file_.empty()) {
    base::DeleteFile(output_file_, false);
    output_file_ = FilePath();
  }

  FilePath output_file;
  if (!base::CreateTemporaryFileInDir(root_directory_, &output_file)) {
    LOG(ERROR) << "Unable to create output file.";
    return FilePath();
  }

  size_t written =
      base::WriteFile(output_file, output_data.c_str(), output_data.length());
  if (written != output_data.length()) {
    LOG(ERROR) << "Unable to write to output file.";
    return FilePath();
  }

  if (chmod(output_file.value().c_str(),
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
    LOG(ERROR) << "Failed to set permissions on " << output_file.value();
    base::DeleteFile(output_file, false);
    return FilePath();
  }
  output_file_ = output_file;
  return output_file_;
}

}  // namespace shill
