Add write_cow functionality

Adding gflags + some basic functionality to this binary. We should be
able to use this to write v2 or v3 cow, and then use inspect_cow to
inspect the contents

Test: write_cow
Change-Id: I44bf5a8c807c4c4759e54624c51e966f2ea18ce9
diff --git a/fs_mgr/libsnapshot/tools/Android.bp b/fs_mgr/libsnapshot/tools/Android.bp
index a7449b4..a1c92c0 100644
--- a/fs_mgr/libsnapshot/tools/Android.bp
+++ b/fs_mgr/libsnapshot/tools/Android.bp
@@ -34,6 +34,7 @@
 
     static_libs: [
         "libsnapshot_cow",
+        "libgflags",
     ],
 
     shared_libs: [
diff --git a/fs_mgr/libsnapshot/tools/write_cow.cpp b/fs_mgr/libsnapshot/tools/write_cow.cpp
index 72fb0f5..bd51174 100644
--- a/fs_mgr/libsnapshot/tools/write_cow.cpp
+++ b/fs_mgr/libsnapshot/tools/write_cow.cpp
@@ -18,10 +18,18 @@
 #include <libsnapshot/cow_compress.h>
 #include <libsnapshot/cow_format.h>
 #include <libsnapshot/cow_writer.h>
-#include <filesystem>
+
+#include <gflags/gflags.h>
+#include <iostream>
 
 #include "android-base/unique_fd.h"
 
+DEFINE_bool(silent, false, "Run silently");
+DEFINE_int32(writer_version, 2, "which version of COW writer to be used");
+DEFINE_bool(write_legacy, false,
+            "Writes a legacy cow_v2 in current directory, this cow was used to test backwards "
+            "compatibility between version 2 and version 3");
+DEFINE_bool(write_header, false, "Test reading/writing just the header");
 using namespace android::snapshot;
 
 // This writes a simple cow v2 file in the current directory. This file will serve as testdata for
@@ -29,7 +37,7 @@
 //
 // WARNING: We should not be overriding this test file, as it will serve as historic marker for what
 // a device with old writer_v2 will write as a cow.
-void write_cow_v2() {
+static void write_legacy_cow_v2() {
     CowOptions options;
     options.cluster_ops = 5;
     options.num_merge_ops = 1;
@@ -58,6 +66,49 @@
     writer->Finalize();
 }
 
-int main() {
-    write_cow_v2();
+static bool WriteCow(const std::string& path) {
+    android::base::unique_fd fd(open(path.c_str(), O_RDONLY));
+    fd.reset(open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0664));
+    if (fd < 0) {
+        PLOG(ERROR) << "could not open " << path << " for writing";
+        return false;
+    }
+    CowOptions options;
+    std::string data = "This is some data, believe it";
+    data.resize(options.block_size, '\0');
+
+    std::unique_ptr<ICowWriter> writer =
+            CreateCowWriter(FLAGS_writer_version, options, std::move(fd));
+    if (!writer) {
+        return false;
+    }
+
+    writer->AddCopy(0, 5);
+    writer->AddRawBlocks(2, data.data(), data.size());
+    writer->AddLabel(1);
+    writer->AddXorBlocks(50, data.data(), data.size(), 24, 10);
+    writer->AddZeroBlocks(5, 10);
+    writer->AddLabel(2);
+    writer->Finalize();
+
+    if (!FLAGS_silent) {
+        std::cout << "Writing COW with writer v" << FLAGS_writer_version << "\n";
+    }
+
+    return true;
+}
+
+int main(int argc, char** argv) {
+    gflags::ParseCommandLineFlags(&argc, &argv, true);
+    if (FLAGS_write_legacy) {
+        write_legacy_cow_v2();
+        return 0;
+    }
+    if (argc < 2) {
+        gflags::ShowUsageWithFlags(argv[0]);
+        return 1;
+    }
+    if (!WriteCow(argv[1])) {
+        return 1;
+    }
 }