// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
#pragma once

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "kudu/gutil/macros.h"
#include "kudu/util/env.h"
#include "kudu/util/oid_generator.h"
#include "kudu/util/random.h"
#include "kudu/util/status.h"

namespace kudu {

class BlockId;

namespace pb_util {
class WritablePBContainerFile;
} // namespace pb_util

namespace fs {

// Corrupts various log block manager on-disk data structures.
class LBMCorruptor {
 public:
  LBMCorruptor(Env* env, std::vector<std::string> data_dirs, uint32_t rand_seed);

  // Initializes a the corruptor, parsing all data directories for containers.
  //
  // Containers created after the call to Init() will not be visible to the
  // corruptor.
  Status Init();

  // Preallocates extra space in a full container (chosen at random). This
  // inconsistency is non-fatal and repairable.
  //
  // Returns an error if a full container could not be found.
  Status PreallocateFullContainer();

  // Adds an "unpunched block" to a full container (chosen at random). An
  // unpunched block is one that has been deleted but whose space was not
  // reclaimed.
  //
  // Returns an error if a container could not be found.
  Status AddUnpunchedBlockToFullContainer();

  // Creates a new incomplete container. This inconsistency is non-fatal and
  // repairable.
  Status CreateIncompleteContainer();

  // Adds a malformed record to a container (chosen at random). This
  // inconsistency is fatal and irreparable.
  //
  // Returns an error if a container could not be found.
  Status AddMalformedRecordToContainer();

  // Adds a misaligned block to a container (chosen at random). The block
  // contains repeated 8-byte sequences of its block id. This inconsistency is
  // non-fatal and irreparable.
  //
  // Returns an error if a container could not be found.
  Status AddMisalignedBlockToContainer();

  // Adds a partial LBM record to a container (chosen at random). This
  // inconsistency is non-fatal and repairable.
  //
  // Once a container has this inconsistency, no future inconsistencies will be
  // added to it.
  //
  // Returns an error if a container could not be found.
  Status AddPartialRecordToContainer();

  // Injects one of the above non-fatal inconsistencies (chosen at random).
  Status InjectRandomNonFatalInconsistency();

 private:
  // Describes an on-disk LBM container.
  struct Container {
    std::string name;
    std::string data_filename;
    std::string metadata_filename;
  };

  // Opens the metadata writer belonging to 'container' for additional writing.
  Status OpenMetadataWriter(
      const Container& container,
      std::unique_ptr<pb_util::WritablePBContainerFile>* writer);

  // Appends a CREATE record to 'writer'.
  static Status AppendCreateRecord(pb_util::WritablePBContainerFile* writer,
                                   BlockId block_id,
                                   int64_t block_offset,
                                   int64_t block_length);

  // Appends a DELETE record to 'writer'.
  static Status AppendDeleteRecord(pb_util::WritablePBContainerFile* writer,
                                   BlockId block_id);

  // Preallocates space at the end of a container's data file for a new block.
  //
  // On success, writes the initial data file's size to 'old_data_file_size'.
  static Status PreallocateForBlock(RWFile* data_file,
                                    RWFile::PreAllocateMode mode,
                                    int64_t block_length,
                                    int64_t* old_data_file_size);

  // Gets a random container subject to the restriction in 'mode'.
  //
  // Returns an error if no such container could be found.
  enum FindContainerMode {
    ANY,
    FULL,
  };
  Status GetRandomContainer(FindContainerMode mode,
                            const Container** container) const;

  // Gets a data directory chosen at random.
  const std::string& GetRandomDataDir() const;

  // Initialized in the constructor.
  Env* env_;
  const std::vector<std::string> data_dirs_;
  mutable Random rand_;
  ObjectIdGenerator oid_generator_;

  // Initialized in Init().
  std::vector<Container> all_containers_;
  std::vector<Container> full_containers_;

  DISALLOW_COPY_AND_ASSIGN(LBMCorruptor);
};

} // namespace fs
} // namespace kudu
