// Copyright 2018 Google LLC
//
// 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 CC_TF_UTILS_H_
#define CC_TF_UTILS_H_

#include <string>
#include <vector>

#include "cc/game.h"
#include "cc/model/features.h"

namespace minigo {
namespace tf_utils {

// Writes a list of tensorflow Example protos to a zlib compressed TFRecord
// file, one for each position in the player's move history.
// Each example contains:
//   x: the input BoardFeatures as bytes.
//   pi: the search pi as a float array, serialized as bytes.
//   outcome: a single float containing the game result +/-1.
// CHECK fails if the binary was not compiled with --define=tf=1.
void WriteGameExamples(const std::string& output_dir,
                       const std::string& output_name,
                       const FeatureDescriptor& feature_desc, const Game& game,
                       const double nv_sample_fraction);

// Writes a list of tensorflow Example protos to the specified
// Bigtable, one example per row, starting at the given row cursor.
void WriteGameExamples(const std::string& gcp_project_name,
                       const std::string& instance_name,
                       const std::string& table_name,
                       const FeatureDescriptor& feature_desc, const Game& game);

// Writes information about an eval game to the specified Bigtable.
void WriteEvalRecord(const std::string& gcp_project_name,
                     const std::string& instance_name,
                     const std::string& table_name, const Game& game,
                     const std::string& sgf_name, const std::string& tag);

// Atomically increment the game counter in the given Bigtable by the given
// delta.  Returns the new value.  Prior value will be returned - delta.
uint64_t IncrementGameCounter(const std::string& gcp_project_name,
                              const std::string& instance_name,
                              const std::string& table_name,
                              const std::string& counter_name, size_t delta);

// Port Minigo games from the given GCS files, which must be in
// `.tfrecord.zz` format.  If game_counter is >=0, use that
// and increment from there.  Otherwise, atomically increment
// and use the value from `table_state=metadata:game_counter`.
void PortGamesToBigtable(const std::string& gcp_project_name,
                         const std::string& instance_name,
                         const std::string& table_name,
                         const std::vector<std::string>& paths,
                         int64_t game_counter = -1);

}  // namespace tf_utils
}  // namespace minigo

#endif  // CC_TF_UTILS_H_
