/*
 * Copyright (C) 2015, 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.
 */
#pragma once

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "io_delegate.h"

namespace android {
namespace aidl {
namespace test {

class FakeIoDelegate : public IoDelegate {
 public:
  FakeIoDelegate() = default;
  virtual ~FakeIoDelegate() = default;

  // non-copyable, non-movable
  FakeIoDelegate(const FakeIoDelegate&) = delete;
  FakeIoDelegate(FakeIoDelegate&&) = delete;
  FakeIoDelegate& operator=(const FakeIoDelegate&) = delete;
  FakeIoDelegate& operator=(FakeIoDelegate&&) = delete;

  // Overrides from the real IoDelegate
  std::unique_ptr<std::string> GetFileContents(
      const std::string& filename,
      const std::string& append_content_suffix = "") const override;
  std::unique_ptr<LineReader> GetLineReader(
      const std::string& file_path) const override;
  bool FileIsReadable(const std::string& path) const override;
  std::unique_ptr<CodeWriter> GetCodeWriter(
      const std::string& file_path) const override;
  void RemovePath(const std::string& file_path) const override;
  android::base::Result<std::vector<std::string>> ListFiles(const std::string& dir) const override;

  // Methods added to facilitate testing.
  void SetFileContents(const std::string& filename,
                       const std::string& contents);
  void AddStubParcelable(const std::string& canonical_name,
                         const std::string& cpp_header);
  void AddStubInterface(const std::string& canonical_name);
  void AddCompoundParcelable(const std::string& canonical_name,
                             const std::vector<std::string>& subclasses);
  void AddBrokenFilePath(const std::string& path);
  // Returns true iff we've previously written to |path|.
  // When we return true, we'll set *contents to the written string.
  bool GetWrittenContents(const std::string& path, std::string* content) const;
  const std::map<std::string, std::string>& InputFiles() const;
  const std::map<std::string, std::string>& OutputFiles() const;

  bool PathWasRemoved(const std::string& path);

 private:
  // Remove leading "./" from |path|.
  std::string CleanPath(const std::string& path) const;

  std::map<std::string, std::string> file_contents_;
  // Normally, writing to files leaves the IoDelegate unchanged, so
  // GetCodeWriter is a const method.  However, for tests, we break this
  // intentionally by storing the written strings.
  mutable std::map<std::string, std::string> written_file_contents_;

  // We normally just write to strings in |written_file_contents_| but for
  // files in this list, we simulate I/O errors.
  std::set<std::string> broken_files_;
  mutable std::set<std::string> removed_files_;
};  // class FakeIoDelegate

}  // namespace test
}  // namespace aidl
}  // namespace android
