enum script_add_result flashScriptPage(const unsigned int page,
                                       const char *data,
                                       const enum script_add_mode mode)
{
        if (page >= MAX_SCRIPT_PAGES) {
                pr_error("lua: invalid script index\r\n");
                return SCRIPT_ADD_RESULT_FAIL;
        }

        switch (mode) {
        case SCRIPT_ADD_MODE_IN_PROGRESS:
        case SCRIPT_ADD_MODE_COMPLETE:
                /* Valid cases.  Carry on */
                break;
        default:
                pr_error_int_msg("lua: Unknown script_add_mode: ", mode);
                return SCRIPT_ADD_RESULT_FAIL;
        }

        static ScriptConfig *g_scriptBuffer;
        if (NULL == g_scriptBuffer) {
                terminate_lua();

                pr_debug("lua: Allocating new script buffer\r\n");
                g_scriptBuffer =
                        (ScriptConfig *) portMalloc(sizeof(ScriptConfig));
                memcpy((void *)g_scriptBuffer, (void *)&g_scriptConfig,
                       sizeof(ScriptConfig));
        }

        if (NULL == g_scriptBuffer) {
                pr_error("lua: Failed to allocate memory for script "
                         "buffer.\r\n");
                return SCRIPT_ADD_RESULT_FAIL;
        }

        char *pageToAdd = g_scriptBuffer->script + page * SCRIPT_PAGE_SIZE;
        strncpy(pageToAdd, data, SCRIPT_PAGE_SIZE);

        if (SCRIPT_ADD_MODE_IN_PROGRESS == mode)
                return SCRIPT_ADD_RESULT_OK;

        pr_info("lua: Completed updating LUA. Flashing... ");
        const int rc = memory_flash_region((void*) &g_scriptConfig,
                                           (void*) g_scriptBuffer,
                                           sizeof(ScriptConfig));
        portFree(g_scriptBuffer);
        g_scriptBuffer = NULL;

        if (0 != rc) {
                pr_info_int_msg("failed with code ", rc);
                return SCRIPT_ADD_RESULT_FAIL;
        }

        pr_info("win!\r\n");
        initialize_lua();
        return SCRIPT_ADD_RESULT_OK;
}
static void open_log_file(struct logging_status *ls)
{
        pr_info("Logging: Opening log file\r\n");
        ls->writing_status = WRITING_INACTIVE;

        const int rc = InitFS();
        if (0 != rc) {
                pr_error_int_msg("Logging: FS init error: ", rc);
                return;
        }

        pr_debug("Logging: FS init success.  Opening file...\r\n");
        // Open a file if one is set, else create a new one.
        ls->writing_status = ls->name[0] ? open_existing_log_file(ls) :
                open_new_log_file(ls);

        if (WRITING_INACTIVE == ls->writing_status) {
                pr_warning_str_msg("Logging: Failed to open: ", ls->name);
                return;
        }

        pr_info_str_msg("Logging: Opened " , ls->name);
        ls->flush_tick = xTaskGetTickCount();
}
enum track_add_result add_track(const Track *track, const size_t index,
                                const enum track_add_mode mode)
{
        if (index >= MAX_TRACK_COUNT) {
                pr_error("tracks: Invalid track index\r\n");
                return TRACK_ADD_RESULT_FAIL;
        }

        switch (mode) {
        case TRACK_ADD_MODE_IN_PROGRESS:
        case TRACK_ADD_MODE_COMPLETE:
                /* Valid cases.  Carry on */
                break;
        default:
                pr_error_int_msg("tracks: Unknown track_add_mode: ", mode);
                return TRACK_ADD_RESULT_FAIL;
        }

        static Tracks *g_tracksBuffer;
        if (NULL == g_tracksBuffer) {

#if LUA_SUPPORT
                lua_task_stop();
#endif /* LUA_SUPPORT */

                pr_debug("tracks: Allocating new tracks buffer\r\n");
                g_tracksBuffer = (Tracks *) portMalloc(sizeof(Tracks));
                memcpy(g_tracksBuffer, (void*) &g_tracks, sizeof(Tracks));
        }

        if (NULL == g_tracksBuffer) {
                pr_error("tracks: Failed to allocate memory for track buffer.\r\n");
                return TRACK_ADD_RESULT_FAIL;
        }

        Track *trackToAdd = g_tracksBuffer->tracks + index;
        memcpy(trackToAdd, track, sizeof(Track));
        g_tracksBuffer->count = index + 1;

        /* If we made it here and are still in progress, then we are done */
        if (TRACK_ADD_MODE_IN_PROGRESS == mode)
                return TRACK_ADD_RESULT_OK;

        /* If here, time to flash and tidy up */
        pr_info("tracks: Completed updating tracks. Flashing... ");
        const int rc = flash_tracks(g_tracksBuffer, sizeof(Tracks));
        portFree(g_tracksBuffer);
        g_tracksBuffer = NULL;

        if (0 != rc) {
                pr_info_int_msg("failed with code ", rc);
                return TRACK_ADD_RESULT_FAIL;
        }

        pr_info("win!\r\n");

#if LUA_SUPPORT
        lua_task_start();
#endif /* LUA_SUPPORT */

        return TRACK_ADD_RESULT_OK;
}