// Copyright 2021 Google LLC
//
// 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 "util.hpp"

#include <flasher/ops.hpp>

#include <cstddef>
#include <cstring>
#include <stdexcept>

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

namespace flasher
{
namespace ops
{

using testing::ElementsAre;
using testing::Return;
using testing::SizeIs;

class EraseTest : public OpTest<testing::StrictMock<MockOrFakeDevice>>
{};

TEST_F(EraseTest, ArgumentValidation)
{
    EXPECT_THROW(erase(d, /*dev_offset=*/0, /*max_size=*/0, /*stride_size=*/0,
                       /*noread=*/false),
                 std::invalid_argument);
    EXPECT_THROW(erase(d, /*dev_offset=*/16, /*max_size=*/0, /*stride_size=*/4,
                       /*noread=*/false),
                 std::invalid_argument);
    erase(d, /*dev_offset=*/0, /*max_size=*/0, /*stride_size=*/4,
          /*noread=*/false);

    EXPECT_THROW(erase(d, /*dev_offset=*/0, /*max_size=*/0,
                       /*stride_size=*/0, /*noread=*/false),
                 std::invalid_argument);
}

TEST_F(EraseTest, NoReadUnalignedTiny)
{
    testing::Sequence seq, seq2;
    df.data[0] = 1_b;
    df.data[3] = 3_b;
    EXPECT_CALL(d, readAt(SizeIs(1), 0)).InSequence(seq);
    EXPECT_CALL(d, readAt(SizeIs(1), 3)).InSequence(seq2);
    EXPECT_CALL(d, eraseBlocks(0, 1)).InSequence(seq, seq2);
    EXPECT_CALL(d, writeAt(ElementsAre(1_b), 0)).InSequence(seq);
    EXPECT_CALL(d, writeAt(ElementsAre(3_b), 3)).InSequence(seq2);
    erase(d, /*dev_offset=*/1, /*max_size=*/2, /*stride_size=*/8,
          /*noread=*/true);
}

TEST_F(EraseTest, NoReadUnalignedMulti)
{
    testing::Sequence seq, seq2;
    df.data[0] = 1_b;
    df.data[6] = 6_b;
    df.data[7] = 7_b;
    EXPECT_CALL(d, readAt(SizeIs(1), 0)).InSequence(seq);
    EXPECT_CALL(d, eraseBlocks(0, 1)).InSequence(seq);
    EXPECT_CALL(d, writeAt(ElementsAre(1_b), 0)).InSequence(seq);
    EXPECT_CALL(d, readAt(SizeIs(2), 6)).InSequence(seq2);
    EXPECT_CALL(d, eraseBlocks(1, 1)).InSequence(seq2);
    EXPECT_CALL(d, writeAt(ElementsAre(6_b, 7_b), 6)).InSequence(seq2);
    erase(d, /*dev_offset=*/1, /*max_size=*/5, /*stride_size=*/4,
          /*noread=*/true);
}

TEST_F(EraseTest, NoRead)
{
    EXPECT_CALL(d, eraseBlocks(1, 2));
    erase(d, /*dev_offset=*/4, /*max_size=*/9, /*stride_size=*/8,
          /*noread=*/true);
}

TEST_F(EraseTest, MisalignedStride)
{
    EXPECT_CALL(d, eraseBlocks(0, 2));
    EXPECT_CALL(d, eraseBlocks(2, 1));
    erase(d, /*dev_offset=*/0, /*max_size=*/16, /*stride_size=*/5,
          /*noread=*/true);
}

TEST_F(EraseTest, LongerStride)
{
    EXPECT_CALL(d, eraseBlocks(0, 3));
    erase(d, /*dev_offset=*/0, /*max_size=*/16, /*stride_size=*/16,
          /*noread=*/true);
}

TEST_F(EraseTest, WithRead)
{
    testing::Sequence seq;
    df.data = {0xff_b, 0xff_b, 0xff_b, 0xff_b, 0_b, 0_b, 0_b, 0_b};
    EXPECT_CALL(d, readAt(SizeIs(4), 0));
    EXPECT_CALL(d, readAt(SizeIs(4), 4)).InSequence(seq);
    EXPECT_CALL(d, eraseBlocks(1, 1)).InSequence(seq);
    erase(d, /*dev_offset=*/0, /*max_size=*/8, /*stride_size=*/4,
          /*noread=*/false);
}

TEST_F(EraseTest, WithReadUnalignedTiny)
{
    testing::Sequence seq, seq2;
    df.data = {1_b, 0_b, 0_b, 3_b};
    EXPECT_CALL(d, readAt(SizeIs(4), 0)).InSequence(seq, seq2);
    EXPECT_CALL(d, eraseBlocks(0, 1)).InSequence(seq, seq2);
    EXPECT_CALL(d, writeAt(ElementsAre(1_b), 0)).InSequence(seq);
    EXPECT_CALL(d, writeAt(ElementsAre(3_b), 3)).InSequence(seq2);
    erase(d, /*dev_offset=*/1, /*max_size=*/2, /*stride_size=*/4,
          /*noread=*/false);
}

TEST_F(EraseTest, WithReadUnalignedTinyNoErase)
{
    df.data = {1_b, 0xff_b, 0xff_b, 3_b};
    EXPECT_CALL(d, readAt(SizeIs(4), 0));
    erase(d, /*dev_offset=*/1, /*max_size=*/2, /*stride_size=*/8,
          /*noread=*/false);
}

TEST_F(EraseTest, WithReadUnalignedMulti)
{
    testing::Sequence seq, seq2;
    df.data = {1_b, 0_b, 0_b, 0_b, 0_b, 0_b, 6_b, 7_b};
    EXPECT_CALL(d, readAt(SizeIs(4), 0)).InSequence(seq);
    EXPECT_CALL(d, eraseBlocks(0, 1)).InSequence(seq);
    EXPECT_CALL(d, writeAt(ElementsAre(1_b), 0)).InSequence(seq);
    EXPECT_CALL(d, readAt(SizeIs(4), 4)).InSequence(seq2);
    EXPECT_CALL(d, eraseBlocks(1, 1)).InSequence(seq2);
    EXPECT_CALL(d, writeAt(ElementsAre(6_b, 7_b), 6)).InSequence(seq2);
    erase(d, /*dev_offset=*/1, /*max_size=*/5, /*stride_size=*/4,
          /*noread=*/false);
}

TEST_F(EraseTest, WithReadUnalignedMultiNoErase)
{
    std::memset(df.data.data(), 0xff, df.data.size());
    df.data[0] = 1_b;
    df.data[10] = 6_b;
    df.data[11] = 7_b;
    EXPECT_CALL(d, readAt(SizeIs(4), 0));
    EXPECT_CALL(d, readAt(SizeIs(4), 4));
    EXPECT_CALL(d, readAt(SizeIs(4), 8));
    erase(d, /*dev_offset=*/1, /*max_size=*/9, /*stride_size=*/4,
          /*noread=*/false);
}

} // namespace ops
} // namespace flasher
