/*
 * 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.
 */

#ifndef AAPT_IO_FILE_H
#define AAPT_IO_FILE_H

#include <list>
#include <memory>
#include <vector>

#include "android-base/macros.h"

#include "Source.h"
#include "io/Data.h"
#include "util/Util.h"

namespace aapt {
namespace io {

// Interface for a file, which could be a real file on the file system, or a
// file inside a ZIP archive.
class IFile {
 public:
  virtual ~IFile() = default;

  // Open the file and return it as a block of contiguous memory. How this
  // occurs is implementation dependent. For example, if this is a file on the file
  // system, it may simply mmap the contents. If this file represents a compressed file in a
  // ZIP archive, it may need to inflate it to memory, incurring a copy.
  // Returns nullptr on failure.
  virtual std::unique_ptr<IData> OpenAsData() = 0;

  // Returns the source of this file. This is for presentation to the user and
  // may not be a valid file system path (for example, it may contain a '@' sign to separate
  // the files within a ZIP archive from the path to the containing ZIP archive.
  virtual const Source& GetSource() const = 0;

  IFile* CreateFileSegment(size_t offset, size_t len);

  // Returns whether the file was compressed before it was stored in memory.
  virtual bool WasCompressed() {
    return false;
  }

 private:
  // Any segments created from this IFile need to be owned by this IFile, so
  // keep them
  // in a list. This will never be read, so we prefer better insertion
  // performance
  // than cache locality, hence the list.
  std::list<std::unique_ptr<IFile>> segments_;
};

// An IFile that wraps an underlying IFile but limits it to a subsection of that file.
class FileSegment : public IFile {
 public:
  explicit FileSegment(IFile* file, size_t offset, size_t len)
      : file_(file), offset_(offset), len_(len) {}

  std::unique_ptr<IData> OpenAsData() override;

  const Source& GetSource() const override { return file_->GetSource(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(FileSegment);

  IFile* file_;
  size_t offset_;
  size_t len_;
};

class IFileCollectionIterator {
 public:
  virtual ~IFileCollectionIterator() = default;

  virtual bool HasNext() = 0;
  virtual IFile* Next() = 0;
};

// Interface for a collection of files, all of which share a common source. That source may
// simply be the filesystem, or a ZIP archive.
class IFileCollection {
 public:
  virtual ~IFileCollection() = default;

  virtual IFile* FindFile(const android::StringPiece& path) = 0;
  virtual std::unique_ptr<IFileCollectionIterator> Iterator() = 0;
};

}  // namespace io
}  // namespace aapt

#endif /* AAPT_IO_FILE_H */
