/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * 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.
 */

/**
 * @file sendbytes_message_demo.c
 *
 * @brief Provides the sample code code for sending messages or byte data.
 *
 * @since 1.0
 * @version 1.0
 */

// Device A:

#include <stdio.h>
#include "session.h"
#include "softbus_config_type.h"

const char *g_pkgNameA = "dms"; // Application bundle name of device A
const char *g_sessionNameA = "ohos.distributedschedule.dms.test";  // Session name of device A

// Network ID generated by device B after devices A and B are networked
const char *g_networkidB = "ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00";
const char *g_groupid = "TEST_GROUP_ID";  // Group ID
static SessionAttribute g_sessionAttr = {
    .dataType = TYPE_BYTES,  // Session type
};

// Notify that the session is set up successfully.
static int OnSessionOpened(int sessionId, int result)
{
    printf("session opened,sesison id = %d\r\n", sessionId);
    return 0;
}

// Notify that the session is closed.
static void OnSessionClosed(int sessionId)
{
    printf("session closed, session id = %d\r\n", sessionId);
}

// Notify that the byte data is received.
static void OnBytesReceived(int sessionId, const void *data, unsigned int len)
{
    printf("session bytes received, session id = %d\r\n", sessionId);
}

// Notify that the message is received.
static void OnMessageReceived(int sessionId, const void *data, unsigned int len)
{
    printf("session msg received, session id = %d\r\n", sessionId);
}

static ISessionListener g_sessionlistenerA = {
    .OnSessionOpened = OnSessionOpened,
    .OnSessionClosed = OnSessionClosed,
    .OnBytesReceived = OnBytesReceived,
    .OnMessageReceived = OnMessageReceived,
};

int main(void)
{
    /*
     * 1. Device A calls CreateSessionServer() to create a session server based on the application bundle name and
     * session name, and registers the callbacks for session opened, session closed, byte received, and message
     * received.
     */
    int ret = CreateSessionServer(g_pkgNameA, g_sessionNameA, &g_sessionlistenerA);
    printf("create session server result = %d\n", ret);

    /*
     * 2. Device A calls OpenSession() to open a session based on the local session name,
     * peer session name, and peer network ID and determine the session channel based on the session type.
     * When the session is opened, a callback will be invoked to notify devices A and B.
     * A session ID is returned for subsequent data sending.
     */
    int sessionId = OpenSession(g_sessionNameA, g_sessionNameB, g_networkidB, g_groupid, &g_sessionAttr);
    printf("open session result = %d\n", sessionId);
    
     /* 3. Device A calls SendBytes() to send byte data or calls SendMessage() to send messages to device B. */
    const char *data = "testdata";
    uint32_t len = strlen(data);
    ret = SendBytes(sessionId, data, len);
    printf("send bytes result = %d\n", ret);
    
    ret = SendMessage(sessionId, data, len);
    printf("send message result = %d\n", ret);
    
     /* 4. After data transmission is complete, device A calls CloseSession() to close the session
      * and instructs device B to close the session.
      */
    CloseSession(sessionId);
    printf("SOFTBUS_OK");
    
     /* 5. After the session is closed, devices A and B call RemoveSessionServer() to remove the session server. */
    ret = RemoveSessionServer(g_pkgNameA, g_sessionNameA);
    printf("remove session server result = %d\n", ret);
}

// Device B:

#include <stdio.h>
#include "session.h"

const char *g_pkgNameB = "dmsB"; // Application bundle name of device B
const char *g_sessionNameB = "ohos.distributedschedule.dms.testB";  // Session name of device B

static int OnSessionOpened(int sessionId, int result)
{
    printf("session opened,sesison id = %d\r\n", sessionId);
    return 0;
}

static void OnSessionClosed(int sessionId)
{
    printf("session closed, session id = %d\r\n", sessionId);
}

static void OnBytesReceived(int sessionId, const void *data, unsigned int len)
{
    printf("session bytes received, session id = %d\r\n", sessionId);
}

static void OnMessageReceived(int sessionId, const void *data, unsigned int len)
{
    printf("session msg received, session id = %d\r\n", sessionId);
}

static ISessionListener g_sessionlistenerB = {
    .OnSessionOpened = OnSessionOpened,
    .OnSessionClosed = OnSessionClosed,
    .OnBytesReceived = OnBytesReceived,
    .OnMessageReceived = OnMessageReceived,
};

int main(void)
{
    /*
     * 1. Device B calls CreateSessionServer() to create a session server based on
     * the application bundle name and session name, and registers the callbacks for
     * session opened, session closed, byte received, and message received.
     */
    int ret = CreateSessionServer(g_pkgNameB, g_sessionNameB, &g_sessionlistenerB);
    printf("create session server result = %d\n", ret);

    /*
     * 2. Upon receiving the session open notification via OnSessionOpened(), device B waits for device A to send data.
     * When receiving data, device B returns the receiving status via OnBytesReceived() or OnMessageReceived().
     */
    
    /* 3. When the data is received, device B closes the session and removes the session server. */
    ret = RemoveSessionServer(g_pkgNameB, g_sessionNameB);
    printf("remove session server result = %d\n", ret);
}