
//  D.swift
//  eGauge
//
//  Created by egauge on 7/26/19.
//  Copyright © 2019 egauge. All rights reserved.
//

//  Common data/code that is used by any method
//

import Foundation
import UIKit

//
//  Static functions to handle JSON structures
//
//  Only need for these routines is that most of the JSON
//  APIs throw can throw expections, which should never
//  occur in this app (we never handle user generated JSON
//  info).  It makes the calling code a lot cleaner and easier
//  to understand if we just handle the exceptions here and,
//  in othe unikely case that an exception does occur, just
//  log it and return null.
//
struct Json
{

//  str2json: convert a string to a JSON object
//
//  str - string to convert
//
static func str2json(_ str: String?) -> Any?
{

    guard let s = str,
          !s.isEmpty,
          let payload = s.data(using: String.Encoding.utf8, allowLossyConversion: false) else {
        return nil
    }
    do {
        let json = try JSONSerialization.jsonObject(with: payload, options: [JSONSerialization.ReadingOptions.mutableContainers])
        return json
    } catch {
        Log.d("JSON encode error: \(s)")
        return nil
    }
}

//  json2str: inverse of str2json, convert JSON object to a string
//
//  json - JSON object to convert
//
static func json2str(_ json: Any) -> String?
{

    do {
        let data1 = try JSONSerialization.data(withJSONObject: json)
        return String(decoding: data1, as: UTF8.self)
    } catch {
        Log.d("json decode error: \(json)")
        return nil
    }
}

//  get_str: get string value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_str(_ json: [String: Any], key: String) -> String?
{

    guard let val = json[key] as? String else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_int: get int value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_int(_ json: [String: Any], key: String) -> Int?
{

    guard let val = json[key] as? Int else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_int64: get 64-bit int value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_int64(_ json: [String: Any], key: String) -> Int64?
{

    guard let val = json[key] as? Int64 else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_bool: get boolean value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_bool(_ json: [String: Any], key: String) -> Bool?
{

    guard let val = json[key] as? Bool else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_float: get float value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_float(_ json: [String: Any], key: String) -> Float?
{

    guard let val = json[key] as? Float else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_double: get double value for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_double(_ json: [String: Any], key: String) -> Double?
{

    guard let val = json[key] as? Double else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

//  get_json: get JSON object for a JSON key
//
//  json - JSON object to search
//  key - key desired
//  def - default value if key doesn't exist
//
static func get_json(_ json: [String: Any], key: String) -> Any?
{

    guard let val = json[key] else {
        Log.d("json:\(key) missing from object")
        return nil
    }
    return val
}

}
