text: // Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
  //
  // 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.
  
  import CONNECTION_STATUS from '../../constants/connection-status'
  import {
    createGetEventMessageSuccessActionType,
    createGetEventMessageFailureActionType,
    createStartEventsStreamActionType,
    createStartEventsStreamSuccessActionType,
    createStartEventsStreamFailureActionType,
    createStopEventsStreamActionType,
    createClearEventsActionType,
  } from '../actions/events'
  
  import { getCombinedDeviceId } from '../../../lib/selectors/id'
  
  const defaultState = {
    events: [],
    error: undefined,
    status: CONNECTION_STATUS.DISCONNECTED,
  }
  
  const createNamedEventReducer = function(reducerName = '') {
    const START_EVENTS = createStartEventsStreamActionType(reducerName)
    const START_EVENTS_SUCCESS = createStartEventsStreamSuccessActionType(reducerName)
    const START_EVENTS_FAILURE = createStartEventsStreamFailureActionType(reducerName)
    const STOP_EVENTS = createStopEventsStreamActionType(reducerName)
    const GET_EVENT_SUCCESS = createGetEventMessageSuccessActionType(reducerName)
    const GET_EVENT_FAILURE = createGetEventMessageFailureActionType(reducerName)
    const CLEAR_EVENTS = createClearEventsActionType(reducerName)
  
    return function(state = defaultState, action) {
      switch (action.type) {
        case START_EVENTS:
          return {
            ...state,
            status: CONNECTION_STATUS.CONNECTING,
          }
        case START_EVENTS_SUCCESS:
          return {
            ...state,
            error: undefined,
            status: CONNECTION_STATUS.CONNECTED,
          }
        case GET_EVENT_SUCCESS:
          return {
            ...state,
            events: [action.event, ...state.events],
          }
        case START_EVENTS_FAILURE:
        case GET_EVENT_FAILURE:
          return {
            ...state,
            error: action.error,
            status: CONNECTION_STATUS.ERROR,
          }
        case STOP_EVENTS:
          return {
            ...state,
            status: CONNECTION_STATUS.DISCONNECTED,
          }
        case CLEAR_EVENTS:
          return {
            ...state,
            events: [],
          }
        default:
          return state
      }
    }
  }
  
  const createNamedEventsReducer = function(reducerName = '') {
    const START_EVENTS = createStartEventsStreamActionType(reducerName)
    const START_EVENTS_SUCCESS = createStartEventsStreamSuccessActionType(reducerName)
    const START_EVENTS_FAILURE = createStartEventsStreamFailureActionType(reducerName)
    const GET_EVENT_SUCCESS = createGetEventMessageSuccessActionType(reducerName)
    const GET_EVENT_FAILURE = createGetEventMessageFailureActionType(reducerName)
    const CLEAR_EVENTS = createClearEventsActionType(reducerName)
    const STOP_EVENTS = createStopEventsStreamActionType(reducerName)
    const event = createNamedEventReducer(reducerName)
  
    return function(state = {}, action) {
      if (!action.id) {
        return state
      }
  
      const id = typeof action.id === 'object' ? getCombinedDeviceId(action.id) : action.id
  
      switch (action.type) {
        case START_EVENTS:
        case START_EVENTS_FAILURE:
        case START_EVENTS_SUCCESS:
        case STOP_EVENTS:
        case GET_EVENT_FAILURE:
        case GET_EVENT_SUCCESS:
        case CLEAR_EVENTS:
          return {
            ...state,
            [id]: event(state[id], action),
          }
        default:
          return state
      }
    }
  }
  
  export default createNamedEventsReducer
  