#include "cblas.h"
#include <iostream>
#include <string>
#include <sstream>
#define N 4

using namespace std;

// Expected reference result string for comparison
string expect = R"(4 7 11 14 )";

void setup() {
  // put your setup code here, to run once:

  // Define scalar alpha for scaling vector x
  float alpha = 3;

  // Define input vector x with 4 elements
  float x[4] = {1.0, 2, 3, 4};
  // Vector x elements: [1, 2, 3, 4]

  // Define input/output vector y with 4 elements
  float y[4] = {1, 1, 2, 2};
  // Vector y elements: [1, 1, 2, 2]

  // Perform the operation y := alpha * x + y using OpenBLAS cblas_saxpy
  // N: vector length
  // alpha: scalar multiplier
  // x: source vector
  // 1: stride of x
  // y: destination vector
  // 1: stride of y
  cblas_saxpy(N, alpha, x, 1, y, 1);

  // Create a stringstream to capture program output
  stringstream ss;
  // Save the current standard output buffer
  streambuf *buffer = cout.rdbuf();
  // Redirect standard output to the stringstream
  cout.rdbuf(ss.rdbuf());

  // Print vector y into the stringstream
  for (int i = 0; i < N; i++) {
    // Print the i-th element of y followed by a space
    cout << y[i] << " ";
  }

  // Restore the original standard output buffer
  cout.rdbuf(buffer);

  // Convert stringstream contents to a string
  string s(ss.str());

  // Print separator line
  cout << "*********************************************************" << endl;
  // Print test result header
  cout << "This is the result:" << endl;
  // Print computed result
  cout << s << endl;
  // Print separator line
  cout << "*********************************************************" << endl;
  // Print reference result header
  cout << "This is the reference:" << endl;
  // Print reference result
  cout << expect << endl;

  // Compare computed result with reference
  if (expect == s)
    // If they match, print test passed message
    cout << "{Test PASS}." << endl;
  else
    // If they do not match, print test failed message
    cout << "{Test FAIL}." << endl;
}

void loop() {
  // put your main code here, to run repeatedly:
}
