/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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.
 */

/**
 * @file
 * Proddata class
 *
 * @author Imagination Technologies
 *
 * @copyright <b>Copyright 2016 by Imagination Technologies Limited and/or its affiliated group companies.</b>
 */

#include "proddata.h"
#ifdef __ANDROID__
#include <android-base/logging.h>
#define DLOG(x) LOG(x)
#else
#include <glog/logging.h>
#endif
#include "device_data.h"
#include "flash_access.h"

/**
 * Format string containing hexadecimal symbols
 * @note string should only have symbols 0-9 A-F
 * @return vector containing raw data
 *
 */

std::vector<uint8_t> FormatString(const std::string &data) {
  int size = data.size();
  std::vector<uint8_t> buf(size/2);
  const char *src = data.c_str();
  int j = 0;
  for (int i = 0; i < size; i += 2) {
    sscanf(src + i, "%02hhx", &buf[j++]);
  }

  return buf;
}

Proddata::Proddata(std::unique_ptr<FlashAccess> flash_access) {
  DLOG(INFO) << "Initialising Proddata";
  device_data_ = std::unique_ptr<DeviceData>(new DeviceData(std::move(flash_access)));
}

Proddata::~Proddata() {
  LOG(INFO) << "Deinitialising Proddata";
}

void Proddata::Write(const std::string &data) {
  LOG(INFO) << "Writing wifi calibration and MAC data";
  if (data.size() % 2 != 0) {
    LOG(ERROR) << "Invalid data given";
#ifdef __ANDROID__
    exit(-1);
#else
    throw std::runtime_error("Invalid data given");
#endif
  }

  std::vector<uint8_t> buf = FormatString(data);
  device_data_->Write(buf);
}

std::vector<uint8_t> Proddata::Read() {
  DLOG(INFO) << "Reading wifi calibration and MAC data";
  return device_data_->Read();
}

std::vector<uint8_t> Proddata::ReadValue(const std::string &name) {
  DLOG(INFO) << "Reading data";
  return device_data_->ReadValue(name);
}
