//
// 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/data_encoding.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.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 |
//   hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
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();
  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();
  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();
  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=",
            brillo::data_encoding::Base64Encode(calc.raw_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());
    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=",
            brillo::data_encoding::Base64Encode(calc.raw_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
