int main(int argc, char ** argv)
{
    int result = 0;
    AwaServerSession * session = NULL;
    AwaServerExecuteOperation * operation = NULL;
    struct gengetopt_args_info ai;
    if (cmdline_parser(argc, argv, &ai) != 0)
    {
        result = 1;
        goto cleanup;
    }

    g_logLevel = ai.debug_given ? 2 : (ai.verbose_given ? 1 : 0);
    AwaLog_SetLevel(ai.debug_given ? AwaLogLevel_Debug : (ai.verbose_given ? AwaLogLevel_Verbose : AwaLogLevel_Warning));

    if (ai.inputs_num == 0)
    {
        Error("Specify one or more resource paths.\n");
        result = 1;
        goto cleanup;
    }

    // Create Session
    session = Server_EstablishSession(ai.ipcAddress_arg, ai.ipcPort_arg);
    if (session == NULL)
    {
        Error("EstablishSession failed\n");
        result = 1;
        goto cleanup;
    }

    operation = AwaServerExecuteOperation_New(session);
    if (operation == NULL)
    {
        Error("AwaServerExecuteOperation_New failed\n");
        result = 1;
        goto cleanup;
    }

    AwaExecuteArguments arguments = { .Data = NULL, .Size = 0 };
    if (ai.stdin_given)
    {
        char buf[BUFSIZ];
        int numBytes = 0;
        while (fread(buf+numBytes, 1, 1, stdin) == 1)
        {
            numBytes++;
        }

        arguments.Data = buf;
        arguments.Size = numBytes;

        Verbose("Read payload from stdin: %s [%zu bytes]\n", buf, arguments.Size);
    }
    else
    {
        Verbose("No payload specified.\n");
    }

    int i = 0;
    for (i = 0; i < ai.inputs_num; ++i)
    {
        Target * target = CreateTarget(ai.inputs[i]);
        if (target != NULL)
        {
            AddTarget(operation, ai.clientID_arg, target, &arguments);
            FreeTarget(&target);
        }
    }

    result = ProcessExecuteOperation(session, operation, ai.clientID_arg);

cleanup:
    if (session)
    {
        Server_ReleaseSession(&session);
    }
    if (operation)
    {
        AwaServerExecuteOperation_Free(&operation);
    }
    cmdline_parser_free(&ai);
    return result;
}
int main(int argc, char ** argv)
{
    AwaServerSession * session = NULL;
    struct gengetopt_args_info ai;
    int result = 0;
    if (cmdline_parser(argc, argv, &ai) != 0)
    {
        result = 1;
        goto cleanup;
    }

    g_logLevel = ai.debug_given ? 2 : (ai.verbose_given ? 1 : 0);
    AwaLog_SetLevel(ai.debug_given ? AwaLogLevel_Debug : (ai.verbose_given ? AwaLogLevel_Verbose : AwaLogLevel_Warning));

    if (ai.inputs_num == 0)
    {
        printf("Specify one or more resource paths.\n");
        result = 1;
        goto cleanup;
    }

    // Create Session
    session = Server_EstablishSession(ai.ipcAddress_arg, ai.ipcPort_arg);
    if (session == NULL)
    {
        Error("EstablishSession failed\n");
        result = 1;
        goto cleanup;
    }

    // Create delete operation
    AwaServerDeleteOperation * operation = AwaServerDeleteOperation_New(session);
    if (operation == NULL)
    {
        Error("AwaServerDeleteOperation_New failed");
        result = 1;
        goto cleanup;
    }

    int i = 0;
    for (i = 0; i < ai.inputs_num; ++i)
    {
        Target * target = CreateTarget(ai.inputs[i]);

        if (target != NULL)
        {
            AddTarget(operation, ai.clientID_arg, target);
            FreeTarget(&target);
        }
    }

    result = ProcessDeleteOperation(operation, ai.clientID_arg);

cleanup:
    if (session)
    {
        Server_ReleaseSession(&session);
    }
    if (operation)
    {
       AwaServerDeleteOperation_Free(&operation);
    }
    cmdline_parser_free(&ai);
    return result;
}
int main(int argc, char ** argv)
{
    int result = 1;
    struct gengetopt_args_info ai;
    AwaServerSession * session = NULL;
    AwaServerWriteOperation * operation = NULL;
    char address[128];
    unsigned int port;
    if (cmdline_parser(argc, argv, &ai) != 0)
    {
        result = 1;
        goto cleanup;
    }

    g_logLevel = ai.debug_given ? 2 : (ai.verbose_given ? 1 : 0);
    AwaLog_SetLevel(ai.debug_given ? AwaLogLevel_Debug : (ai.verbose_given ? AwaLogLevel_Verbose : AwaLogLevel_Warning));

    if (ai.inputs_num == 0 && ai.create_given == 0)
    {
        Error("Specify one or more resource paths.\n");
        result = 1;
        goto cleanup;
    }

    port = ai.ipcPort_arg;
    strncpy(address, ai.ipcAddress_arg, strlen(ai.ipcAddress_arg)+1);

    // Establish Awa Session with the daemon
    session = Server_EstablishSession(address, port);
    if (session == NULL)
    {
        Error("Failed to establish Awa Session\n");
        result = 1;
        goto cleanup;
    }

    AwaWriteMode mode = AwaWriteMode_Update;
    if (ai.replace_given)
        mode = AwaWriteMode_Replace;
    operation = AwaServerWriteOperation_New(session, mode);
    if (operation == NULL)
    {
        Error("AwaServerWriteOperation_New failed\n");
        Server_ReleaseSession(&session);
        result = 1;
        goto cleanup;
    }

    // Add create directives first
    int count = 0;
    count = CreateTargets(session, operation, ai.clientID_arg, ai.create_arg, ai.create_given);

    // Add target paths and values from the command line
    int i = 0;
    for (i = 0; i < ai.inputs_num; ++i)
    {
        Target * target = CreateTarget(ai.inputs[i]);
        if (target != NULL)
        {
            char * value = Server_GetValue(session, target, ai.inputs[i]);
            if (value != NULL)
            {
                if (AddTargetWithValue(session, operation, target, value) == 0)
                {
                    ++count;
                }

                free(value);
                value = NULL;
            }
            FreeTarget(&target);
        }
    }
    if (count > 0)
    {
        result = ProcessWriteOperation(operation, ai.clientID_arg);
    }

cleanup:
    if (operation)
    {
        AwaServerWriteOperation_Free(&operation);
    }
    if (session)
    {
        Server_ReleaseSession(&session);
    }
    cmdline_parser_free(&ai);
    return result;
}
int main(int argc, char ** argv)
{
    int result = 0;
    AwaServerObserveOperation * operation;
    struct gengetopt_args_info ai;
    AwaServerSession * session = NULL;
    Target ** targets = NULL;

    // Catch CTRL-C to ensure clean-up
    signal(SIGINT, INThandler);

    if (cmdline_parser(argc, argv, &ai) != 0)
    {
        exit(1);
    }

    g_logLevel = ai.debug_given ? 2 : (ai.verbose_given ? 1 : 0);
    AwaLog_SetLevel(ai.debug_given ? AwaLogLevel_Debug : (ai.verbose_given ? AwaLogLevel_Verbose : AwaLogLevel_Warning));

    if (ai.inputs_num == 0)
    {
        Error("Specify one or more resource paths.\n");
        result = 1;
        goto cleanup;
    }

    session = Server_EstablishSession(ai.ipcAddress_arg, ai.ipcPort_arg);
    if (session != NULL)
    {
        operation = AwaServerObserveOperation_New(session);
        if (operation == NULL)
        {
            Error("Failed to create observe operation\n");
            exit(1);
        }

        targets = malloc(ai.inputs_num * sizeof(Target *));

        ObserveContext observeContext;
        observeContext.targets = targets;
        observeContext.numTargets = ai.inputs_num;
        observeContext.quiet = ai.quiet_given; // pass the quiet parameter as our context
        int count = 0;
        int i = 0;
        for (i = 0; i < ai.inputs_num; ++i)
        {
            targets[i] = CreateTarget(ai.inputs[i]);
            if (targets[i] != NULL)
            {
                count = ObserveTarget(operation, ai.clientID_arg, targets[i], &observeContext) ? count + 1 : count;
            }
        }

        if (AwaServerObserveOperation_Perform(operation, OPERATION_PERFORM_TIMEOUT) != AwaError_Success)
        {
            Error("Failed to perform observe operation\n");
            goto cleanup;
        }

        int validCount = count;
        const AwaServerObserveResponse * response = AwaServerObserveOperation_GetResponse(operation, ai.clientID_arg);
        ObservationNode * currentObservation = g_observationListHead;
        ObservationNode * nextObservation;
        while (currentObservation != NULL)
        {
            nextObservation = currentObservation->next;
            const AwaPathResult * pathResult = NULL;

            AwaServerObservation * observation = (AwaServerObservation *)(currentObservation->observation);
            const char * path = AwaServerObservation_GetPath(observation);

            pathResult = AwaServerObserveResponse_GetPathResult(response, path);
            if (AwaPathResult_GetError(pathResult) != AwaError_Success)
            {
                Error("Failed to observe to %s: %s\n", path, AwaError_ToString(AwaPathResult_GetError(pathResult)));
                validCount--;
            }
            currentObservation = nextObservation;
        }

        AwaServerObserveOperation_Free(&operation);

        // Wait if there's something to wait for
        Debug("count %d\n", count);
        if (count > 0)
        {
            if (validCount > 0)
            {
                Wait(session, ai.waitTime_arg, ai.waitCount_arg);
            }
            CancelObservationFromTargets(session, ai.clientID_arg);
        }
    }
    else
    {
        Error("Failed to establish Awa Session\n");
        result = 1;
    }
cleanup:
    if (session)
    {
        FreeObservationList();
        Server_ReleaseSession(&session);
    }
    if (targets)
    {
        int i;
        for (i = 0; i < ai.inputs_num; ++i)
        {
            if (targets[i] != NULL)
            {
                FreeTarget(&targets[i]);
            }
        }
        free(targets);
    }
    cmdline_parser_free(&ai);
    return result;
}