/*
 *
 *    Copyright (c) 2018 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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.
 */

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/ConnectivityManager.h>
#include <Weave/DeviceLayer/internal/ServiceDirectoryManager.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelAgent.h>
#include <new>

#if WEAVE_CONFIG_ENABLE_TUNNELING

using namespace ::nl;
using namespace ::nl::Weave;
using namespace ::nl::Weave::Profiles::WeaveTunnel;
using namespace ::nl::Inet;

namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {

WeaveTunnelAgent ServiceTunnelAgent;

WEAVE_ERROR InitServiceTunnelAgent()
{
    WEAVE_ERROR err;

    new (&ServiceTunnelAgent) WeaveTunnelAgent();

#if WEAVE_DEVICE_CONFIG_ENABLE_FIXED_TUNNEL_SERVER

    {
        IPAddress tunnelServerAddr;
        const char * tunnelServerAddrStr;
        uint16_t tunnelServerAddrStrLen;
        uint16_t tunnelServerPort;

        err = ParseHostAndPort(WEAVE_DEVICE_CONFIG_TUNNEL_SERVER_ADDRESS, strlen(WEAVE_DEVICE_CONFIG_TUNNEL_SERVER_ADDRESS),
                tunnelServerAddrStr, tunnelServerAddrStrLen, tunnelServerPort);
        if (err != WEAVE_NO_ERROR || !IPAddress::FromString(tunnelServerAddrStr, tunnelServerAddrStrLen, tunnelServerAddr))
        {
            WeaveLogError(DeviceLayer, "Invalid value specified for TUNNEL_SERVER_ADDRESS config: %s", CONFIG_TUNNEL_SERVER_ADDRESS);
            ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
        }

        if (tunnelServerPort == 0)
        {
            tunnelServerPort = WEAVE_PORT;
        }

        ESP_LOGW(TAG, "Using fixed tunnel server address: %s", CONFIG_TUNNEL_SERVER_ADDRESS);

        err = ServiceTunnelAgent.Init(&InetLayer, &ExchangeMgr, kServiceEndpoint_WeaveTunneling,
                tunnelServerAddr, kWeaveAuthMode_CASE_ServiceEndPoint);
        SuccessOrExit(err);

        // This is necessary because the Init() function doesn't provide a way to specify the port.
        ServiceTunnelAgent.SetDestination(kServiceEndpoint_WeaveTunneling, tunnelServerAddr, tunnelServerPort);
    }

#else // WEAVE_DEVICE_CONFIG_ENABLE_FIXED_TUNNEL_SERVER

#if !WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY
#error "Weave service directory feature not enabled (WEAVE_CONFIG_ENABLE_SERVICE_DIRECTORY)"
#endif

    err = ServiceTunnelAgent.Init(&InetLayer, &ExchangeMgr, kServiceEndpoint_WeaveTunneling,
            kWeaveAuthMode_CASE_ServiceEndPoint, &ServiceDirectoryMgr);
    SuccessOrExit(err);

#endif // WEAVE_DEVICE_CONFIG_ENABLE_FIXED_TUNNEL_SERVER

exit:
    if (err != WEAVE_NO_ERROR)
    {
        WeaveLogError(DeviceLayer, "InitServiceTunnelAgent() failed: %s", ErrorStr(err));
    }
    return err;
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace Weave
} // namespace nl

#endif // WEAVE_CONFIG_ENABLE_TUNNELING
