/*
 * Copyright (C) 2019 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 <sys/resource.h>
#include <sys/types.h>

#include <optional>
#include <string>
#include <vector>

#include <android-base/unique_fd.h>
#include <cutils/iosched_policy.h>

#include "interprocess_fifo.h"
#include "mount_namespace.h"
#include "result.h"

namespace android {
namespace init {

// Constants used by Service::Start() for communication between parent and child.
enum ServiceCode : uint8_t {
    kActivatingCgroupsFailed,
    kCgroupsActivated,
    kSetSidFinished,
};

class Descriptor {
  public:
    Descriptor(const std::string& name, android::base::unique_fd fd)
        : name_(name), fd_(std::move(fd)){};

    // Publish() unsets FD_CLOEXEC from the FD and publishes its name via setenv().  It should be
    // called when starting a service after fork() and before exec().
    void Publish() const;

  private:
    std::string name_;
    android::base::unique_fd fd_;
};

struct SocketDescriptor {
    std::string name;
    int type = 0;
    uid_t uid = 0;
    gid_t gid = 0;
    int perm = 0;
    std::string context;
    bool passcred = false;
    bool listen = false;
    bool persist = false;

    // Create() creates the named unix domain socket in /dev/socket and returns a Descriptor object.
    // It should be called when starting a service, before calling fork(), such that the socket is
    // synchronously created before starting any other services, which may depend on it.
    Result<Descriptor> Create(const std::string& global_context) const;
};

struct FileDescriptor {
    std::string name;
    std::string type;

    Result<Descriptor> Create() const;
};

struct NamespaceInfo {
    int flags;
    // Pair of namespace type, path to name.
    std::vector<std::pair<int, std::string>> namespaces_to_enter;
};
Result<void> EnterNamespaces(const NamespaceInfo& info, const std::string& name,
                             std::optional<MountNamespace> override_mount_namespace);

struct ProcessAttributes {
    std::string console;
    IoSchedClass ioprio_class;
    int ioprio_pri;
    std::vector<std::pair<int, rlimit>> rlimits;
    std::optional<uid_t> parsed_uid;
    gid_t gid;
    std::vector<gid_t> supp_gids;
    int priority;
    bool stdio_to_kmsg;

    uid_t uid() const { return parsed_uid.value_or(0); }
};

inline bool RequiresConsole(const ProcessAttributes& attr) {
    return !attr.console.empty();
}

Result<void> SetProcessAttributes(const ProcessAttributes& attr, InterprocessFifo setsid_finished);

Result<void> WritePidToFiles(std::vector<std::string>* files);

}  // namespace init
}  // namespace android
