/*
 * Copyright (C) 2016 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 ANDROID_OS_DUMPSTATE_UTIL_H_
#define ANDROID_OS_DUMPSTATE_UTIL_H_

#include <cstdint>
#include <string>

namespace android {
namespace os {
namespace dumpstate {

/*
 * Defines the Linux account that should be executing a command.
 */
enum PrivilegeMode {
    /* Explicitly change the `uid` and `gid` to be `shell`.*/
    DROP_ROOT,
    /* Don't change the `uid` and `gid`. */
    DONT_DROP_ROOT,
    /* Prefix the command with `/PATH/TO/su root`. Won't work non user builds. */
    SU_ROOT
};

/*
 * Defines what should happen with the main output stream (`stdout` or fd) of a command.
 */
enum OutputMode {
    /* Don't change main output. */
    NORMAL_OUTPUT,
    /* Redirect main output to `stderr`. */
    REDIRECT_TO_STDERR
};

/*
 * Value object used to set command options.
 *
 * Typically constructed using a builder with chained setters. Examples:
 *
 *  CommandOptions::WithTimeout(20).AsRoot().Build();
 *  CommandOptions::WithTimeout(10).Always().RedirectStderr().Build();
 *
 * Although the builder could be used to dynamically set values. Example:
 *
 *  CommandOptions::CommandOptionsBuilder options =
 *  CommandOptions::WithTimeout(10);
 *  if (!is_user_build()) {
 *    options.AsRoot();
 *  }
 *  RunCommand("command", {"args"}, options.Build());
 */
class CommandOptions {
  private:
    class CommandOptionsValues {
      private:
        CommandOptionsValues(int64_t timeout);

        int64_t timeout_;
        bool always_;
        PrivilegeMode account_mode_;
        OutputMode output_mode_;
        std::string logging_message_;

        friend class CommandOptions;
        friend class CommandOptionsBuilder;
    };

    CommandOptions(const CommandOptionsValues& values);

    const CommandOptionsValues values;

  public:
    class CommandOptionsBuilder {
      public:
        /* Sets the command to always run, even on `dry-run` mode. */
        CommandOptionsBuilder& Always();
        /* Sets the command's PrivilegeMode as `SU_ROOT` */
        CommandOptionsBuilder& AsRoot();
        /* If !IsUserBuild(), sets the command's PrivilegeMode as `SU_ROOT` */
        CommandOptionsBuilder& AsRootIfAvailable();
        /* Sets the command's PrivilegeMode as `DROP_ROOT` */
        CommandOptionsBuilder& DropRoot();
        /* Sets the command's OutputMode as `REDIRECT_TO_STDERR` */
        CommandOptionsBuilder& RedirectStderr();
        /* When not empty, logs a message before executing the command.
         * Must contain a `%s`, which will be replaced by the full command line, and end on `\n`. */
        CommandOptionsBuilder& Log(const std::string& message);
        /* Builds the command options. */
        CommandOptions Build();

      private:
        CommandOptionsBuilder(int64_t timeout);
        CommandOptionsValues values;
        friend class CommandOptions;
    };

    /** Gets the command timeout, in seconds. */
    int64_t Timeout() const;
    /* Checks whether the command should always be run, even on dry-run mode. */
    bool Always() const;
    /** Gets the PrivilegeMode of the command. */
    PrivilegeMode PrivilegeMode() const;
    /** Gets the OutputMode of the command. */
    OutputMode OutputMode() const;
    /** Gets the logging message header, it any. */
    std::string LoggingMessage() const;

    /** Creates a builder with the requied timeout. */
    static CommandOptionsBuilder WithTimeout(int64_t timeout);

    // Common options.
    static CommandOptions DEFAULT;
    static CommandOptions AS_ROOT;
};

/*
 * System properties helper.
 */
class PropertiesHelper {
    friend class DumpstateBaseTest;

  public:
    /*
     * Gets whether device is running a `user` build.
     */
    static bool IsUserBuild();

    /*
     * When running in dry-run mode, skips the real dumps and just print the section headers.
     *
     * Useful when debugging dumpstate or other bugreport-related activities.
     *
     * Dry-run mode is enabled by setting the system property `dumpstate.dry_run` to true.
     */
    static bool IsDryRun();

  private:
    static std::string build_type_;
    static int dry_run_;
};

/*
 * Forks a command, waits for it to finish, and returns its status.
 *
 * |fd| file descriptor that receives the command's 'stdout'.
 * |title| description of the command printed on `stdout` (or empty to skip
 * description).
 * |full_command| array containing the command (first entry) and its arguments.
 *                Must contain at least one element.
 * |options| optional argument defining the command's behavior.
 */
int RunCommandToFd(int fd, const std::string& title, const std::vector<std::string>& full_command,
                   const CommandOptions& options = CommandOptions::DEFAULT);

/*
 * Dumps the contents of a file into a file descriptor.
 *
 * |fd| file descriptor where the file is dumped into.
 * |title| description of the command printed on `stdout` (or empty to skip
 * description).
 * |path| location of the file to be dumped.
 */
int DumpFileToFd(int fd, const std::string& title, const std::string& path);

/*
 * Finds the process id by process name.
 * |ps_name| the process name we want to search for
 */
int GetPidByName(const std::string& ps_name);

}  // namespace dumpstate
}  // namespace os
}  // namespace android

#endif  // ANDROID_OS_DUMPSTATE_UTIL_H_
