/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.

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 TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_
#define TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_

#include <complex>
#include <vector>

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
#include "tensorflow/lite/kernels/internal/types.h"
#include "tensorflow/lite/string_util.h"

namespace tflite {

inline RuntimeShape GetTensorShape(std::vector<int32_t> data) {
  return RuntimeShape(data.size(), data.data());
}

// A list of tensors in a format that can be used by kernels like split and
// concatenation.
template <typename T>
class VectorOfTensors {
 public:
  // Build with the tensors in 'tensor_list'.
  VectorOfTensors(const TfLiteContext& context,
                  const TfLiteIntArray& tensor_list) {
    int num_tensors = tensor_list.size;

    all_data_.reserve(num_tensors);
    all_shape_.reserve(num_tensors);
    all_shape_ptr_.reserve(num_tensors);

    for (int i = 0; i < num_tensors; ++i) {
      TfLiteTensor* t = &context.tensors[tensor_list.data[i]];
      all_data_.push_back(GetTensorData<T>(t));
      all_shape_.push_back(GetTensorShape(t));
    }

    // Taking the pointer from inside a std::vector is only OK if the vector is
    // never modified, so we populate all_shape in the previous loop and then we
    // are free to grab iterators here.
    for (int i = 0; i < num_tensors; ++i) {
      all_shape_ptr_.push_back(&all_shape_[i]);
    }
  }
  // Return a pointer to the data pointers of all tensors in the list. For
  // example:
  //   float* const* f = v.data();
  //   f[0][1] is the second element of the first tensor.
  T* const* data() const { return all_data_.data(); }

  // Return a pointer the shape pointers of all tensors in the list. For
  // example:
  //   const RuntimeShape* const* d = v.dims();
  //   dims[1] are the dimensions of the second tensor in the list.
  const RuntimeShape* const* shapes() const { return all_shape_ptr_.data(); }

 private:
  std::vector<T*> all_data_;
  std::vector<RuntimeShape> all_shape_;
  std::vector<RuntimeShape*> all_shape_ptr_;
};

// A list of quantized tensors in a format that can be used by kernels like
// split and concatenation.
class VectorOfQuantizedTensors : public VectorOfTensors<uint8> {
 public:
  // Build with the tensors in 'tensor_list'.
  VectorOfQuantizedTensors(const TfLiteContext& context,
                           const TfLiteIntArray& tensor_list)
      : VectorOfTensors<uint8>(context, tensor_list) {
    for (int i = 0; i < tensor_list.size; ++i) {
      TfLiteTensor* t = &context.tensors[tensor_list.data[i]];
      zero_point_.push_back(t->params.zero_point);
      scale_.push_back(t->params.scale);
    }
  }

  const float* scale() const { return scale_.data(); }
  const int32* zero_point() const { return zero_point_.data(); }

 private:
  std::vector<int32> zero_point_;
  std::vector<float> scale_;
};

// Writes randomly accessed values from `input` sequentially into `output`.
template <typename T>
class SequentialTensorWriter {
 public:
  SequentialTensorWriter(const TfLiteTensor* input, TfLiteTensor* output) {
    input_data_ = GetTensorData<T>(input);
    output_ptr_ = GetTensorData<T>(output);
  }
  SequentialTensorWriter(const T* input_data, T* output_data)
      : input_data_(input_data), output_ptr_(output_data) {}

  void Write(int position) { *output_ptr_++ = input_data_[position]; }
  void WriteN(int position, int len) {
    memcpy(output_ptr_, &input_data_[position], sizeof(T) * len);
    output_ptr_ += len;
  }

 private:
  const T* input_data_;
  T* output_ptr_;
};

// String ops are not yet supported on platforms w/ static memory.
#ifndef TF_LITE_STATIC_MEMORY
template <>
class SequentialTensorWriter<string> {
 public:
  SequentialTensorWriter(const TfLiteTensor* input, TfLiteTensor* output)
      : input_(input), output_(output) {}
  ~SequentialTensorWriter() { buffer_.WriteToTensor(output_, nullptr); }

  void Write(int position) { this->WriteN(position, 1); }
  void WriteN(int position, int len) {
    for (int i = 0; i < len; i++) {
      buffer_.AddString(GetString(input_, position + i));
    }
  }

 private:
  const TfLiteTensor* input_;
  TfLiteTensor* output_;
  DynamicBuffer buffer_;
};
#endif  // TF_LITE_STATIC_MEMORY

}  // namespace tflite

#endif  // TENSORFLOW_LITE_KERNELS_INTERNAL_TENSOR_H_
