import {
  Brick as BrickDefaults,
  MainBrick as MainBrickConstants,
  Primitive as PrimitiveDefaults,
  TestInput as TestInputConstants
} from '../../components/constants'

import { inputSlotPosition } from '../../utils'
import {
  BRICK,
  MAIN_BRICK,
  PRIMITIVE,
  SELECTABLE_PIPE,
  TEST_INPUT
} from '../../utils/componentNames'

let id = 1
// TODO: Generate id's with an UID function ??
const nextId = () => id++

export const newBrick = (brick) => {
  const { arity, moduleName, name } = brick
  let inputSlots = {}

  for(var i=0; i < arity; i++) {
    const id = nextId()

    inputSlots[id] = {
      id,
      index: i
    }
  }

  return {
    componentName: BRICK,
    id: nextId(),
    inputSlots,
    moduleName,
    name,
    outputSlots: [
      { id: nextId() }
    ],
    position: BrickDefaults.defaultPosition,
    size: BrickDefaults.defaultSize
  }
}

const newMainBrick = (mainBrickId) => {
  const inputSlotIds = [nextId(), nextId()]

  return {
    componentName: MAIN_BRICK,
    id: mainBrickId,
    innerIds: [],
    inputSlots: {
      [inputSlotIds[0]]: {
        id: inputSlotIds[0],
        index: 0
      },
      [inputSlotIds[1]]: {
        id: inputSlotIds[1],
        index: 1
      }
    },
    outputSlots: [
      { id: nextId() }
    ],
    position: MainBrickConstants.defaultPosition,
    size: MainBrickConstants.defaultSize
  }
}

export const newPrimitive = (type) => {
  return {
    componentName: PRIMITIVE,
    id: nextId(),
    position: PrimitiveDefaults.defaultPosition,
    size: PrimitiveDefaults.defaultSize,
    // react or redux ignore pair with value `undefined`
    value: null
  }
}

export const newPipe = (payload) => {
  const { input, output } = payload

  return {
    componentName: SELECTABLE_PIPE,
    id: nextId(),
    input,
    output,
    type: "null",
    valueId: input.slotId
  }
}

export const newTestInputs = (mainBrick) => {
  let testInputs = {}

  for(var id in mainBrick.inputSlots) {
    const inputSlot = mainBrick.inputSlots[id]

    testInputs[id] = {
      componentName: TEST_INPUT,
      id: inputSlot.id,
      slotPosition: inputSlotPosition(mainBrick, inputSlot),
      size: TestInputConstants.defaultSize,
      type: "null",
      value: null
    }
  }

  return testInputs
}

export const newWorkspace = () => {
  const mainBrickId = nextId()
  const mainBrick = newMainBrick(mainBrickId)
  const testInputs = newTestInputs(mainBrick)

  let testInputIds = []

  for(var testInput in testInputs)
    testInputIds.push(testInputs[testInput].id)

  return {
    entities: {
      [mainBrickId]: {
        ...mainBrick,
        testInputIds
      },
      ...testInputs
    },
    mainBrickId: mainBrickId,
    selectionState: {
      dragStarted: false,
      element: { },
      pipe: {
        input: { },
        output: { }
      }
    },
    unitTests: [
      {
        values: { }
      }
    ]
  }
}

export const pipeConnectedToElement = (element, elementId) => {
  return element.componentName == SELECTABLE_PIPE &&
    (element.input.elementId == elementId ||
     element.output.elementId == elementId)
}

@@ -953,16 +953,48 @@
 extId()%5D
+%0A  const outputSlotId = nextId()
 %0A%0A  retu
@@ -1277,38 +1277,90 @@
 ts: 
-%5B
+%7B%0A      %5BoutputSlotId%5D: %7B
 %0A      
-%7B
+ 
  id: 
-nextId()
+outputSlotId,%0A        index: 0%0A     
  %7D%0A    
-%5D
+%7D
 ,%0A  

Convert 'outputSlots' from array to dictionary