import React, {PropTypes} from 'react'
import {withRouter} from 'react-router'
import {connect} from 'react-redux'
import {getSources} from 'src/shared/apis'
import {loadSources as loadSourcesAction} from 'src/shared/actions/sources'
import {showDatabases} from 'src/shared/apis/metaQuery'

// Acts as a 'router middleware'. The main `App` component is responsible for
// getting the list of data nodes, but not every page requires them to function.
// Routes that do require data nodes can be nested under this component.
const CheckSources = React.createClass({
  propTypes: {
    addFlashMessage: PropTypes.func,
    children: PropTypes.node,
    params: PropTypes.shape({
      sourceID: PropTypes.string,
    }).isRequired,
    router: PropTypes.shape({
      push: PropTypes.func.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      pathname: PropTypes.string.isRequired,
    }).isRequired,
    sources: PropTypes.array.isRequired,
    loadSourcesAction: PropTypes.func.isRequired,
  },

  getInitialState() {
    return {
      isFetching: true,
    }
  },

  componentDidMount() {
    getSources().then(({data: {sources}}) => {
      this.props.loadSourcesAction(sources)
      this.setState({isFetching: false})
    }).catch(() => {
      this.props.addFlashMessage({type: 'error', text: "Unable to connect to Chronograf server"})
      this.setState({isFetching: false})
    })
  },

  componentWillUpdate(nextProps, nextState) {
    const {router, location, params, addFlashMessage, sources} = nextProps
    const {isFetching} = nextState
    const source = sources.find((s) => s.id === params.sourceID)
    const defaultSource = sources.find((s) => s.default === true)
    if (!isFetching && !source) {
      if (defaultSource) {
        const rest = location.pathname.match(/\/sources\/\d+?\/(.+)/)
        return router.push(`/sources/${defaultSource.id}/${rest[1]}`)
      }
      return router.push(`/sources/new?redirectPath=${location.pathname}`)
    }

    if (!isFetching && !location.pathname.includes("/manage-sources")) {
      // Do simple query to proxy to see if the source is up.
      showDatabases(source.links.proxy).catch(() => {
        addFlashMessage({type: 'error', text: `Unable to connect to source`})
      })
    }
  },

  render() {
    const {params, sources} = this.props
    const {isFetching} = this.state
    const source = sources.find((s) => s.id === params.sourceID)

    if (isFetching || !source) {
      return <div className="page-spinner" />
    }

    return this.props.children && React.cloneElement(this.props.children, Object.assign({}, this.props, {
      source,
    }))
  },
})

function mapStateToProps(state) {
  return {
    sources: state.sources,
  }
}

export default connect(mapStateToProps, {loadSourcesAction})(withRouter(CheckSources))

@@ -526,89 +526,481 @@
 nst 
-CheckSources = React.createClass(%7B%0A  propTypes: %7B%0A    addFlashMessage: PropTypes.
+%7B%0A  arrayOf,%0A  func,%0A  node,%0A  shape,%0A  string,%0A%7D = PropTypes%0Aconst CheckSources = React.createClass(%7B%0A  propTypes: %7B%0A    sources: arrayOf(shape(%7B%0A      links: shape(%7B%0A        proxy: string.isRequired,%0A        self: string.isRequired,%0A        kapacitors: string.isRequired,%0A        queries: string.isRequired,%0A        permissions: string.isRequired,%0A        users: string.isRequired,%0A        databases: string.isRequired,%0A      %7D).isRequired,%0A    %7D)),%0A    addFlashMessage: 
 func
@@ -1015,26 +1015,16 @@
 ildren: 
-PropTypes.
 node,%0A  
@@ -1033,26 +1033,16 @@
 params: 
-PropTypes.
 shape(%7B%0A
@@ -1057,26 +1057,16 @@
 urceID: 
-PropTypes.
 string,%0A
@@ -1096,26 +1096,16 @@
 router: 
-PropTypes.
 shape(%7B%0A
@@ -1116,26 +1116,16 @@
   push: 
-PropTypes.
 func.isR
@@ -1166,26 +1166,16 @@
 cation: 
-PropTypes.
 shape(%7B%0A
@@ -1190,26 +1190,16 @@
 thname: 
-PropTypes.
 string.i
@@ -1236,94 +1236,537 @@
     
-s
+loadS
 ources
-: PropTypes.array.isRequired,%0A    loadSourcesAct
+Action: func.isRequired,%0A  %7D,%0A%0A  childContextTypes: %7B%0A    source: shape(%7B%0A      links: shape(%7B%0A        proxy: string.isRequired,%0A        self: string.isRequired,%0A        kapacitors: string.isRequired,%0A        queries: string.isRequired,%0A        permiss
 ion
+s
 : 
-PropTypes.func.isRequired,
+string.isRequired,%0A        users: string.isRequired,%0A        databases: string.isRequired,%0A      %7D).isRequired,%0A    %7D),%0A  %7D,%0A%0A  getChildContext() %7B%0A    const %7Bsources, params: %7BsourceID%7D%7D = this.props%0A    return %7Bsource: sources.find((s) =%3E s.id === sourceID)%7D
 %0A  %7D

Move source context declaration to top level