// Copyright 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 "net/base/net_log_logger.h"

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "net/base/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class NetLogLoggerTest : public testing::Test {
 public:
  virtual void SetUp() {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    log_path_ = temp_dir_.path().AppendASCII("NetLogFile");
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath log_path_;
};

TEST_F(NetLogLoggerTest, GeneratesValidJSONForNoEvents) {
  // Create and destroy a logger.
  FILE* file = base::OpenFile(log_path_, "w");
  ASSERT_TRUE(file);
  scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
  scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));
  logger.reset();

  std::string input;
  ASSERT_TRUE(base::ReadFileToString(log_path_, &input));

  base::JSONReader reader;
  scoped_ptr<base::Value> root(reader.ReadToValue(input));
  ASSERT_TRUE(root) << reader.GetErrorMessage();

  base::DictionaryValue* dict;
  ASSERT_TRUE(root->GetAsDictionary(&dict));
  base::ListValue* events;
  ASSERT_TRUE(dict->GetList("events", &events));
  ASSERT_EQ(0u, events->GetSize());
}

// Make sure the log level is LOG_STRIP_PRIVATE_DATA by default.
TEST_F(NetLogLoggerTest, LogLevel) {
  FILE* file = base::OpenFile(log_path_, "w");
  ASSERT_TRUE(file);
  scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
  NetLogLogger logger(file, *constants);

  NetLog net_log;
  logger.StartObserving(&net_log);
  EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, logger.log_level());
  EXPECT_EQ(NetLog::LOG_STRIP_PRIVATE_DATA, net_log.GetLogLevel());
  logger.StopObserving();

  logger.set_log_level(NetLog::LOG_ALL_BUT_BYTES);
  logger.StartObserving(&net_log);
  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, logger.log_level());
  EXPECT_EQ(NetLog::LOG_ALL_BUT_BYTES, net_log.GetLogLevel());
  logger.StopObserving();
}

TEST_F(NetLogLoggerTest, GeneratesValidJSONWithOneEvent) {
  FILE* file = base::OpenFile(log_path_, "w");
  ASSERT_TRUE(file);
  scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
  scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));

  const int kDummyId = 1;
  NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
  NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
                               source,
                               NetLog::PHASE_BEGIN,
                               base::TimeTicks::Now(),
                               NULL);
  NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);
  logger->OnAddEntry(entry);
  logger.reset();

  std::string input;
  ASSERT_TRUE(base::ReadFileToString(log_path_, &input));

  base::JSONReader reader;
  scoped_ptr<base::Value> root(reader.ReadToValue(input));
  ASSERT_TRUE(root) << reader.GetErrorMessage();

  base::DictionaryValue* dict;
  ASSERT_TRUE(root->GetAsDictionary(&dict));
  base::ListValue* events;
  ASSERT_TRUE(dict->GetList("events", &events));
  ASSERT_EQ(1u, events->GetSize());
}

TEST_F(NetLogLoggerTest, GeneratesValidJSONWithMultipleEvents) {
  FILE* file = base::OpenFile(log_path_, "w");
  ASSERT_TRUE(file);
  scoped_ptr<base::Value> constants(NetLogLogger::GetConstants());
  scoped_ptr<NetLogLogger> logger(new NetLogLogger(file, *constants));

  const int kDummyId = 1;
  NetLog::Source source(NetLog::SOURCE_SPDY_SESSION, kDummyId);
  NetLog::EntryData entry_data(NetLog::TYPE_PROXY_SERVICE,
                               source,
                               NetLog::PHASE_BEGIN,
                               base::TimeTicks::Now(),
                               NULL);
  NetLog::Entry entry(&entry_data, NetLog::LOG_ALL);

  // Add the entry multiple times.
  logger->OnAddEntry(entry);
  logger->OnAddEntry(entry);
  logger.reset();

  std::string input;
  ASSERT_TRUE(base::ReadFileToString(log_path_, &input));

  base::JSONReader reader;
  scoped_ptr<base::Value> root(reader.ReadToValue(input));
  ASSERT_TRUE(root) << reader.GetErrorMessage();

  base::DictionaryValue* dict;
  ASSERT_TRUE(root->GetAsDictionary(&dict));
  base::ListValue* events;
  ASSERT_TRUE(dict->GetList("events", &events));
  ASSERT_EQ(2u, events->GetSize());
}

}  // namespace

}  // namespace net
