/**
 * @return array
 * @throws Exception
 * @throws IllegalArgumentException
 */
function gd_dashboard_index_variables () {
    $dashboards = array();
    $active_datasource_name = gd_datasource_find_active();
    $current_dashboard = gd_dashboard_get_current();
    global $user;

    if ( gd_account_user_is_admin() ) {

        // can see all datasources
        $datasources = gd_datasource_get_all();

        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else if ( !$active_datasource_name ) {
            if (isset($_GET['ds'])) {
                gd_datasource_set_active($_GET['ds']);
            } else {
                gd_datasource_set_active(key($datasources));
            }
        }

        // don't pick up any dashboards if there are no published datamarts - causes logic bomb further down
        if ( !empty($datasources) ) {
            $dashboards = gd_dashboard_findall_by_datasource(LOAD_ENTITY);
        }

    } else if ( $user->uid ) {

        // get view privileges for all dashboards
        $results = gd_account_user_get_dashboards();

        // pick up the datasources from the dashboards
        $datasources = gd_account_user_get_datasources();
        foreach ( $results as $dashboard ) {
            if ( !isset($datasources[get_node_field_value($dashboard,'field_dashboard_datasource')]) ) {
                $datasource = gd_datasource_get(get_node_field_value($dashboard,'field_dashboard_datasource'));
                $datasources[$datasource->name] = $datasource;
            }
        }

        // set current datasource
        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else {
            if ( !$active_datasource_name ) {
                if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) {
                    gd_datasource_set_active($_GET['ds']);
                } else {
                    reset($results);
                    try {
                        if (!empty($results[key($results)])) {
                            $active_datasource_name = get_node_field_value($results[key($results)],'field_dashboard_datasource');
                            gd_datasource_set_active($active_datasource_name);
                        } else {
                            return 'You have not been granted permission to view any dashboards.';
                        }
                    } catch (Exception $e) {
                        drupal_set_message('No default datasource set.', 'error');
                        LogHelper::log_error($e->getMessage());
                    }
                }
            }
        }

        // remove dashboards that do not belong to datasource of current dashboard
        $active_datasource_name = gd_datasource_get_active();
        $dashboards = array();
        foreach ( $results as $key => $dashboard ) {
            if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) {
                $dashboards[$key] = $dashboard;
            }
        }

        // remove dashboards that were not created by the user
        if ( gd_datasource_is_property($active_datasource_name, 'personal') ) {
            global $user;
            $userCreatedDashboards = array();
            foreach ( $dashboards as $key => $dashboard ) {
                if ( $user->uid == $dashboard->uid ) {
                    $userCreatedDashboards[$key] = $dashboard;
                }
            }
            $dashboards = $userCreatedDashboards; // overwrite dashboard list
        }

    } else {

        // get datasources that belong to the dashboards
        // weed out dashboards with missing datasource
        $datasources = array();
        $publicDashboards = array();
        foreach ( gd_dashboard_get_dashboards_public(LOAD_ENTITY) as $dashboard ) {
            $datasourceName = get_node_field_value($dashboard,'field_dashboard_datasource');
            $datasource = gd_datasource_find($datasourceName);
            if ( !$datasource ) {
                continue;
            }
            $publicDashboards[$dashboard->nid] = $dashboard;
            if ( !isset($datasources[$datasourceName]) ) {
                $datasources[$datasource->name] = $datasource;
            }
        }

        // set current datamart
        if ( $current_dashboard ) {
            gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource'));
        } else {
            if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) {
                gd_datasource_set_active($_GET['ds']);
            } else {
                gd_datasource_set_active(get_node_field_value($publicDashboards[key($publicDashboards)],'field_dashboard_datasource'));
            }
        }

        // remove dashboards that do not belong to datamart of current dashboard
        $active_datasource_name = gd_datasource_get_active();
        $dashboards = array();
        foreach ( $publicDashboards as $key => $dashboard ) {
            if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) {
                $dashboards[$key] = $dashboard;
            }
        }
    }

    reset($datasources);
    reset($dashboards);

    // sort the dashboard list by name
    usort($dashboards, function($a, $b) {
        if (strtolower($a->title) === strtolower($b->title)){
            return strnatcmp($a->title,$b->title);
        }
        return strnatcasecmp($a->title,$b->title);
    });

    // which dashboard to display
    if ( $current_dashboard ) {
        $dashboard = $current_dashboard;
    } else if (!empty($dashboards) ) {
        $dashboard = $dashboards[0];
    } else {
        $dashboard = null;
    }

    $display_dashboards = array();
    if ( !empty($dashboards) ) {
        $dashboard_ids = array(); // index of any parents from $dashboards
        $drilldown_dashboard_ids = array();
        foreach ( $dashboards as $d ) {
            $config = new GD_DashboardConfig($d);
            $dashboard_ids[] = (int)$d->nid;
            foreach( $config->drilldowns as $drilldown) {
                if ( is_object($drilldown->dashboard) ) {
                    $drilldown_dashboard_ids[] = (int)$drilldown->dashboard->id; // for backwards compatibility
                } else {
                    $drilldown_dashboard_ids[] = (int)$drilldown->dashboard;
                }
            }
        }
        $drilldown_dashboard_ids = array_unique($drilldown_dashboard_ids);
        $display_dashboard_ids = array_diff($dashboard_ids, $drilldown_dashboard_ids);
        $display_dashboards = array();
        foreach ( $dashboards as $d ) {
            if ( in_array($d->nid,$display_dashboard_ids) ) {
                $display_dashboards[] = $d;
            }
        }
        // if initial dashboard is a drilldown dashboard, load first non-drilldown dashboard instead
        if ( in_array($dashboard->nid, $drilldown_dashboard_ids) && empty($_GET['id']) ) {
            $dashboardKeys = array_keys($display_dashboard_ids);
            $dashboard = $dashboards[array_shift($dashboardKeys)];
        }
    }

    // force a dashboard id into the url for javascript libs
    // TODO doing a redirect is wasteful, find some other way
    if ( empty($_GET['id']) &&  isset($dashboard) ) {
        drupal_goto('dashboards',array('query'=>array('id'=>$dashboard->nid)));
    }

    foreach ( $datasources as $k => $ds ) {
        if ( $ds->name == gd_datasource_get_active() ) {
            $datasources[$k]->active = true;
        }
    }

    return array($datasources, $dashboard, $display_dashboards);
}
if ( isset($_GET['datasource']) ) {
    $datasourceName = $_REQUEST['datasource'];
}

if ( isset($_POST['datasourceName']) ) {
    $datasourceName = $_POST['datasourceName'];
}

gd_datasource_set_active($datasourceName);

if ( !gd_account_user_is_admin() && !gd_account_user_is_datasource_admin(null,gd_datasource_get_active()) ) {
    echo "<h3>Access Denied</h3>";
    drupal_exit();
}

$datasource = gd_datasource_get($datasourceName);


$deleteWarningMessage = "Are you sure you want to delete \'".($datasource->publicName)."\'? ".
                        "This will delete all the associated Dashboards, Reports and Datasets from that topic. ".
                        "This action cannot be undone.";

if ( isset($_POST['editdatamart']) && $_POST['editdatamart'] == "yes" ) {

    $errors = array();

    // validate
    if ( trim($_POST['publicName']) == '' ) {
        $errors[] = "Name can not be blank";
    }