/*
 * Copyright 2019 Google LLC, Andrew Hines
 *
 * 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 VISQOL_INCLUDE_VISQOL_API_H
#define VISQOL_INCLUDE_VISQOL_API_H

#include <string>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/types/span.h"
#include "src/proto/similarity_result.pb.h"  // Generated by cc_proto_library rule
#include "src/proto/visqol_config.pb.h"  // Generated by cc_proto_library rule
#include "visqol_manager.h"

namespace Visqol {
class VisqolApi {
 public:
  /**
   * Currently, 48k is the only sample rate supported by ViSQOL Audio. This
   * constant is used to check for that.
   */
  static const size_t k48kSampleRate;

  /**
   * Create an instance of the ViSQOL API, using the given config data.
   * See the proto file of this config for the config details.
   *
   * The given config contains information specific to the signals to be
   * compared. Therefore, a new instance of the ViSQOL API must be created for
   * each comparison to be made.
   *
   * @param config The config needed to create this API instance.
   *
   * @return An 'ok' status if successfully created. Else, an error status.
   */
  absl::Status Create(const VisqolConfig config);

  /**
   * Perform a ViSQOL comparison on the given input signals.
   *
   * Both signals must have the same sample rate. This sample rate is set in
   * the constructor.
   *
   * @param reference The reference input signal.
   * @param degraded The degraded input signal.
   *
   * @return If the comparison completes successfully, the similarity results
   *    will be returned. See the proto file of the similarity results for
   *    details. If the comparison fails, an error is returned.
   */
  absl::StatusOr<SimilarityResultMsg> Measure(
      const absl::Span<double>& reference, const absl::Span<double>& degraded);

 private:
  /**
   * The instance of ViSQOL that will be used for comparing the signals.
   */
  Visqol::VisqolManager visqol_;

  /**
   * The sample rate of the input signals to be compared.
   */
  size_t sample_rate_;
};
}  // namespace Visqol

#endif  // VISQOL_INCLUDE_VISQOL_API_H
