// Copyright (c) 2009 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 <math.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <glib.h>
#include <gtest/gtest.h>

#include "update_engine/libcurl_http_fetcher.h"
#include "update_engine/omaha_hash_calculator.h"
#include "update_engine/utils.h"

using std::string;
using std::vector;

namespace chromeos_update_engine {

// Generated by running this on a linux shell:
// $ echo -n hi | openssl dgst -sha256 -binary | openssl base64
static const char kExpectedHash[] =
    "j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=";
static const unsigned char kRawExpectedRawHash[] = {
  0x8f, 0x43, 0x43, 0x46, 0x64, 0x8f, 0x6b, 0x96,
  0xdf, 0x89, 0xdd, 0xa9, 0x01, 0xc5, 0x17, 0x6b,
  0x10, 0xa6, 0xd8, 0x39, 0x61, 0xdd, 0x3c, 0x1a,
  0xc8, 0x8b, 0x59, 0xb2, 0xdc, 0x32, 0x7a, 0xa4
};

class OmahaHashCalculatorTest : public ::testing::Test {
 public:
  const char *kExpectedRawHash;
  const char *kExpectedRawHashEnd;

  OmahaHashCalculatorTest() :
    kExpectedRawHash(reinterpret_cast<const char*>(kRawExpectedRawHash)),
    kExpectedRawHashEnd(kExpectedRawHash + arraysize(kRawExpectedRawHash))
  {}
};

TEST_F(OmahaHashCalculatorTest, SimpleTest) {
  OmahaHashCalculator calc;
  calc.Update("hi", 2);
  calc.Finalize();
  EXPECT_EQ(kExpectedHash, calc.hash());
  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
  EXPECT_TRUE(raw_hash == calc.raw_hash());
}

TEST_F(OmahaHashCalculatorTest, MultiUpdateTest) {
  OmahaHashCalculator calc;
  calc.Update("h", 1);
  calc.Update("i", 1);
  calc.Finalize();
  EXPECT_EQ(kExpectedHash, calc.hash());
  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
  EXPECT_TRUE(raw_hash == calc.raw_hash());
}

TEST_F(OmahaHashCalculatorTest, ContextTest) {
  OmahaHashCalculator calc;
  calc.Update("h", 1);
  string calc_context = calc.GetContext();
  calc.Finalize();
  OmahaHashCalculator calc_next;
  calc_next.SetContext(calc_context);
  calc_next.Update("i", 1);
  calc_next.Finalize();
  EXPECT_EQ(kExpectedHash, calc_next.hash());
  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
  EXPECT_TRUE(raw_hash == calc_next.raw_hash());
}

TEST_F(OmahaHashCalculatorTest, BigTest) {
  OmahaHashCalculator calc;

  int digit_count = 1;
  int next_overflow = 10;
  for (int i = 0; i < 1000000; i++) {
    char buf[8];
    if (i == next_overflow) {
      next_overflow *= 10;
      digit_count++;
    }
    ASSERT_EQ(digit_count, snprintf(buf, sizeof(buf), "%d", i)) << " i = " << i;
    calc.Update(buf, strlen(buf));
  }
  calc.Finalize();

  // Hash constant generated by running this on a linux shell:
  // $ C=0
  // $ while [ $C -lt 1000000 ]; do
  //     echo -n $C
  //     let C=C+1
  //   done | openssl dgst -sha256 -binary | openssl base64
  EXPECT_EQ("NZf8k6SPBkYMvhaX8YgzuMgbkLP1XZ+neM8K5wcSsf8=", calc.hash());
}

TEST_F(OmahaHashCalculatorTest, UpdateFileSimpleTest) {
  string data_path;
  ASSERT_TRUE(
      utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
  ScopedPathUnlinker data_path_unlinker(data_path);
  ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));

  static const int kLengths[] = { -1, 2, 10 };
  for (size_t i = 0; i < arraysize(kLengths); i++) {
    OmahaHashCalculator calc;
    EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
    EXPECT_TRUE(calc.Finalize());
    EXPECT_EQ(kExpectedHash, calc.hash());
    vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
    EXPECT_TRUE(raw_hash == calc.raw_hash());
  }

  OmahaHashCalculator calc;
  EXPECT_EQ(0, calc.UpdateFile(data_path, 0));
  EXPECT_EQ(1, calc.UpdateFile(data_path, 1));
  EXPECT_TRUE(calc.Finalize());
  // echo -n h | openssl dgst -sha256 -binary | openssl base64
  EXPECT_EQ("qqlAJmTxpB9A67xSyZk+tmrrNmYClY/fqig7ceZNsSM=", calc.hash());
}

TEST_F(OmahaHashCalculatorTest, RawHashOfFileSimpleTest) {
  string data_path;
  ASSERT_TRUE(
      utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
  ScopedPathUnlinker data_path_unlinker(data_path);
  ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));

  static const int kLengths[] = { -1, 2, 10 };
  for (size_t i = 0; i < arraysize(kLengths); i++) {
    vector<char> exp_raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
    vector<char> raw_hash;
    EXPECT_EQ(2, OmahaHashCalculator::RawHashOfFile(data_path,
                                                    kLengths[i],
                                                    &raw_hash));
    EXPECT_TRUE(exp_raw_hash == raw_hash);
  }
}

TEST_F(OmahaHashCalculatorTest, UpdateFileNonexistentTest) {
  OmahaHashCalculator calc;
  EXPECT_EQ(-1, calc.UpdateFile("/some/non-existent/file", -1));
}

TEST_F(OmahaHashCalculatorTest, AbortTest) {
  // Just make sure we don't crash and valgrind doesn't detect memory leaks
  {
    OmahaHashCalculator calc;
  }
  {
    OmahaHashCalculator calc;
    calc.Update("h", 1);
  }
}

}  // namespace chromeos_update_engine
