
import { NativeModules, Image } from 'react-native';
import uuid from 'uuid/v1';

const { RNImageRecognition, RNTensorFlowInference, RNTensorFlowGraph, RNTensorFlowGraphOperations } = NativeModules;

class TensorFlowOperation {
  constructor(id, opName) {
    this.id = id
    this.opName = opName
  }

  inputListLength(name) {
    return RNTensorFlowGraphOperations.inputListLength(this.id, this.opName, name);
  }

  name() {
    return RNTensorFlowGraphOperations.name(this.id, this.opName)
  }

  numOutputs() {
    return RNTensorFlowGraphOperations.numOutputs(this.id, this.opName)
  }

  output(index) {
    return RNTensorFlowGraphOperations.output(this.id, this.opName, index)
  }

  outputList(index, length) {
    return RNTensorFlowGraphOperations.outputList(this.id, this.opName, index, length)
  }

  outputListLength(name) {
    return RNTensorFlowGraphOperations.outputListLength(this.id, this.opName, name)
  }

  type() {
    return RNTensorFlowGraphOperations.type(this.id, this.opName)
  }
}

class TensorFlowGraph {
  constructor(id) {
    this.id = id
  }

  importGraphDef(graphDef) {
    return RNTensorFlowGraph.importGraphDef(this.id, graphDef)
  }

  importGraphDefWithPrefix(graphDef, prefix) {
    return RNTensorFlowGraph.importGraphDefWithPrefix(this.id, graphDef, prefix)
  }

  toGraphDef() {
    return RNTensorFlowGraph.toGraphDef(this.id)
  }

  operation(name) {
    return new TensorFlowOperation(this.id, name)
  }

  close() {
    return RNTensorFlowGraph.close(this.id)
  }
}

class TensorFlowInference {

  constructor(modelLocation) {
    this.id = uuid()
    const resolvedModelLocation = Image.resolveAssetSource(modelLocation) != null
      ? Image.resolveAssetSource(modelLocation).uri
      : modelLocation
    this.init = RNTensorFlowInference.initTensorFlowInference(this.id, resolvedModelLocation)
    this.tfGraph = new TensorFlowGraph(this.id)
  }

  async feed(data) {
    await this.init
    return RNTensorFlowInference.feed(this.id, data)
  }

  async run(outputNames, withStats) {
    await this.init
    return RNTensorFlowInference.run(this.id, outputNames, withStats !== undefined ? withStats : false)
  }

  async fetch(outputName) {
    await this.init
    return RNTensorFlowInference.fetch(this.id, outputName)
  }

  async graph() {
    await this.init
    return this.tfGraph
  }

  async close() {
    await this.init
    return RNTensorFlowInference.close(this.id)
  }
}

class ImageRecognition {
  constructor(data) {
    this.id = uuid()
    data['model'] = Image.resolveAssetSource(data['model']) != null
      ? Image.resolveAssetSource(data['model']).uri
      : data['model']

    data['label'] = Image.resolveAssetSource(data['label']) != null
      ? Image.resolveAssetSource(data['label']).uri
      : data['label']

    this.init = RNImageRecognition.initImageRecognizer(this.id, data)
  }

  async recognize(data) {
    await this.init

    data['image'] = Image.resolveAssetSource(data['image']) != null
      ? Image.resolveAssetSource(data['image']).uri
      : data['image']

    return RNTensorFlowInference.feed(this.id, data)
  }
}

export TensorFlowInference;
export ImageRecognition;

@@ -2662,16 +2662,17 @@
 a%5B'label
+s
 '%5D = Ima
@@ -2704,16 +2704,17 @@
 a%5B'label
+s
 '%5D) != n
@@ -2761,16 +2761,17 @@
 a%5B'label
+s
 '%5D).uri%0A
@@ -2789,16 +2789,17 @@
 a%5B'label
+s
 '%5D%0A%0A    

Rename label to labels