// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIB_VFS_CPP_FLAGS_H_
#define LIB_VFS_CPP_FLAGS_H_

#include <fuchsia/io/cpp/fidl.h>

namespace vfs {

class Flags {
 public:
  Flags() = delete;

  static bool IsReadable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_READABLE) != 0; }

  static bool IsWritable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_WRITABLE) != 0; }

  static bool IsAdminable(uint32_t flags) { return (flags & fuchsia::io::OPEN_RIGHT_ADMIN) != 0; }

  static bool IsDirectory(uint32_t flags) {
    return (flags & fuchsia::io::OPEN_FLAG_DIRECTORY) != 0;
  }

  static bool IsNotDirectory(uint32_t flags) {
    return (flags & fuchsia::io::OPEN_FLAG_NOT_DIRECTORY) != 0;
  }

  static bool ShouldDescribe(uint32_t flags) {
    return (flags & fuchsia::io::OPEN_FLAG_DESCRIBE) != 0;
  }

  static bool IsNodeReference(uint32_t flags) {
    return (flags & fuchsia::io::OPEN_FLAG_NODE_REFERENCE) != 0;
  }

  static bool ShouldCloneWithSameRights(uint32_t flags) {
    return (flags & fuchsia::io::CLONE_FLAG_SAME_RIGHTS) != 0;
  }

  static bool IsPosix(uint32_t flags) { return (flags & fuchsia::io::OPEN_FLAG_POSIX) != 0; }

  // All known rights.
  static constexpr uint32_t kFsRights = fuchsia::io::OPEN_RIGHT_READABLE |
                                        fuchsia::io::OPEN_RIGHT_WRITABLE |
                                        fuchsia::io::OPEN_RIGHT_ADMIN;

  // All lower 16 bits are reserved for future rights extensions.
  static constexpr uint32_t kFsRightsSpace = 0x0000FFFF;

  // Flags which can be modified by FIDL File::SetFlags.
  static constexpr uint32_t kSettableStatusFlags = fuchsia::io::OPEN_FLAG_APPEND;

  // All flags which indicate state of the connection (excluding rights).
  static constexpr uint32_t kStatusFlags =
      kSettableStatusFlags | fuchsia::io::OPEN_FLAG_NODE_REFERENCE;

  // Returns true if the rights flags in |flags_a| does not exceed
  // those in |flags_b|.
  static bool StricterOrSameRights(uint32_t flags_a, uint32_t flags_b) {
    uint32_t rights_a = flags_a & kFsRights;
    uint32_t rights_b = flags_b & kFsRights;
    return (rights_a & ~rights_b) == 0;
  }

  // Perform basic flags validation relevant to Directory::Open and Node::Clone.
  // Returns false if the flags combination is invalid.
  static bool InputPrecondition(uint32_t flags) {
    // If the caller specified an unknown right, reject the request.
    if ((flags & Flags::kFsRightsSpace) & ~Flags::kFsRights) {
      return false;
    }

    // Explicitly reject NODE_REFERENCE together with any invalid flags.
    if (Flags::IsNodeReference(flags)) {
      constexpr uint32_t kValidFlagsForNodeRef =
          fuchsia::io::OPEN_FLAG_NODE_REFERENCE | fuchsia::io::OPEN_FLAG_DIRECTORY |
          fuchsia::io::OPEN_FLAG_NOT_DIRECTORY | fuchsia::io::OPEN_FLAG_DESCRIBE;
      if (flags & ~kValidFlagsForNodeRef) {
        return false;
      }
    }

    return true;
  }
};

}  // namespace vfs

#endif  // LIB_VFS_CPP_FLAGS_H_
