//
// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/common/hash_calculator.h"

#include <math.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <brillo/secure_blob.h>
#include <gtest/gtest.h>

#include "update_engine/common/libcurl_http_fetcher.h"
#include "update_engine/common/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 uint8_t kExpectedRawHash[] = {
  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 HashCalculatorTest : public ::testing::Test {
 public:
  HashCalculatorTest() {}
};

TEST_F(HashCalculatorTest, SimpleTest) {
  HashCalculator calc;
  calc.Update("hi", 2);
  calc.Finalize();
  EXPECT_EQ(kExpectedHash, calc.hash());
  brillo::Blob raw_hash(std::begin(kExpectedRawHash),
                        std::end(kExpectedRawHash));
  EXPECT_TRUE(raw_hash == calc.raw_hash());
}

TEST_F(HashCalculatorTest, MultiUpdateTest) {
  HashCalculator calc;
  calc.Update("h", 1);
  calc.Update("i", 1);
  calc.Finalize();
  EXPECT_EQ(kExpectedHash, calc.hash());
  brillo::Blob raw_hash(std::begin(kExpectedRawHash),
                        std::end(kExpectedRawHash));
  EXPECT_TRUE(raw_hash == calc.raw_hash());
}

TEST_F(HashCalculatorTest, ContextTest) {
  HashCalculator calc;
  calc.Update("h", 1);
  string calc_context = calc.GetContext();
  calc.Finalize();
  HashCalculator calc_next;
  calc_next.SetContext(calc_context);
  calc_next.Update("i", 1);
  calc_next.Finalize();
  EXPECT_EQ(kExpectedHash, calc_next.hash());
  brillo::Blob raw_hash(std::begin(kExpectedRawHash),
                        std::end(kExpectedRawHash));
  EXPECT_TRUE(raw_hash == calc_next.raw_hash());
}

TEST_F(HashCalculatorTest, BigTest) {
  HashCalculator 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(HashCalculatorTest, 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++) {
    HashCalculator calc;
    EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
    EXPECT_TRUE(calc.Finalize());
    EXPECT_EQ(kExpectedHash, calc.hash());
    brillo::Blob raw_hash(std::begin(kExpectedRawHash),
                          std::end(kExpectedRawHash));
    EXPECT_TRUE(raw_hash == calc.raw_hash());
  }

  HashCalculator 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(HashCalculatorTest, 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++) {
    brillo::Blob exp_raw_hash(std::begin(kExpectedRawHash),
                              std::end(kExpectedRawHash));
    brillo::Blob raw_hash;
    EXPECT_EQ(2, HashCalculator::RawHashOfFile(data_path,
                                               kLengths[i],
                                               &raw_hash));
    EXPECT_TRUE(exp_raw_hash == raw_hash);
  }
}

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

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

}  // namespace chromeos_update_engine
