/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *    * Neither the name of The Linux Foundation nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/* External Includes */
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <vector>

/* Internal Includes */
#include "IOffloadManager.h"
#include "PrefixParser.h"

/* Avoiding namespace pollution */
using IP_FAM = ::IOffloadManager::IP_FAM;
using Prefix = ::IOffloadManager::Prefix;

using ::std::string;
using ::std::vector;


/* ------------------------------ PUBLIC ------------------------------------ */
PrefixParser::PrefixParser() {
    mLastErr = "No Err";
} /* PrefixParser */

bool PrefixParser::add(vector<string> in) {
    return add(in, IP_FAM::INVALID);
} /* add */

bool PrefixParser::add(string in) {
    return add(in, IP_FAM::INVALID);
} /* add */

bool PrefixParser::addV4(string in) {
    return add(in, IP_FAM::V4);
} /* addV4 */

bool PrefixParser::addV4(vector<string> in) {
    return add(in, IP_FAM::V4);
} /* addV4 */

bool PrefixParser::addV6(string in) {
    return add(in, IP_FAM::V6);
} /* addV6 */

bool PrefixParser::addV6(vector<string> in) {
    for (size_t i = 0; i < in.size(); i++) {
        if (!addV6(in[i]))
            return false;
    }
    return true;
} /* addV6 */

int PrefixParser::size() {
    return mPrefixes.size();
} /* size */

bool PrefixParser::allAreFullyQualified() {
    for (size_t i = 0; i < mPrefixes.size(); i++) {
        if (mPrefixes[i].fam == IP_FAM::V4) {
            uint32_t masked = mPrefixes[i].v4Addr & mPrefixes[i].v4Mask;
            if (masked != mPrefixes[i].v4Addr)
                return false;
        } else {
            uint32_t masked[4];
            masked[0] = mPrefixes[i].v6Addr[0] & mPrefixes[i].v6Mask[0];
            masked[1] = mPrefixes[i].v6Addr[1] & mPrefixes[i].v6Mask[1];
            masked[2] = mPrefixes[i].v6Addr[2] & mPrefixes[i].v6Mask[2];
            masked[3] = mPrefixes[i].v6Addr[3] & mPrefixes[i].v6Mask[3];
            for (int j = 0; j < 4; j++) {
                if (masked[j] != mPrefixes[i].v6Addr[j])
                    return false;
            }
        }
    }
    return true;
} /* allAreFullyQualified */

Prefix PrefixParser::getFirstPrefix() {
    if (size() >= 1)
        return mPrefixes[0];
    return makeBlankPrefix(IP_FAM::INVALID);
} /* getFirstPrefix */

string PrefixParser::getLastErrAsStr() {
    return mLastErr;
} /* getLastErrAsStr */


/* ------------------------------ PRIVATE ----------------------------------- */
bool PrefixParser::add(vector<string> in, IP_FAM famHint) {
    if (in.size() == 0)
        return false;

    for (size_t i = 0; i < in.size(); i++) {
        if (!add(in[i], famHint))
            return false;
    }
    return true;
} /* add */

bool PrefixParser::add(string in, IP_FAM famHint) {
    if (in.length() == 0) {
        mLastErr = "Failed to parse string, length = 0...";
        return false;
    }

    if (famHint == IP_FAM::INVALID)
        famHint = guessIPFamily(in);

    string subnet;
    string addr;

    if (!splitIntoAddrAndMask(in, addr, subnet)) {
        mLastErr = "Failed to split into Address and Mask(" + in + ")";
        return false;
    }

    int mask = parseSubnetMask(subnet, famHint);
    if (!isMaskValid(mask, famHint)) {
        mLastErr = "Invalid mask";
        return false;
    }

    Prefix pre = makeBlankPrefix(famHint);

    if (famHint == IP_FAM::V4) {
        if (!parseV4Addr(addr, pre)) {
            mLastErr = "Failed to parse V4 Address(" + addr + ")";
            return false;
        }
    } else if (!parseV6Addr(addr, pre)) {
        mLastErr = "Failed to parse V6 Address(" + addr + ")";
        return false;
    }

    if (famHint == IP_FAM::V4 && !populateV4Mask(mask, pre)) {
        mLastErr = "Failed to populate IPv4 Mask(" + std::to_string(mask)
                + ", " + addr + ")";
        return false;
    } else if (!populateV6Mask(mask, pre)) {
        mLastErr = "Failed to populate IPv6 Mask(" + std::to_string(mask)
                + ", " + addr + ")";
        return false;
    }

    mPrefixes.push_back(pre);
    return true;
} /* add */

/* Assumption (based on man inet_pton)
 *
 * X represents a hex character
 * d represents a base 10 digit
 * / represents the start of the subnet mask
 *              (assume that it can be left off of all below combinations)
 *
 * IPv4 Addresses always look like the following:
 *      ddd.ddd.ddd.ddd/dd
 *
 * IPv6 Addresses can look a few different ways:
 *      x:x:x:x:x:x:x:x/ddd
 *      x::x/ddd
 *      x:x:x:x:x:x:d.d.d.d/ddd
 *
 * Therefore, if a presentation of an IP Address contains a colon, then it
 * may not be a valid IPv6, but, it is definitely not valid IPv4.  If a
 * presentation of an IP Address does not contain a colon, then it may not be
 * a valid IPv4, but, it is definitely not IPv6.
 */
IP_FAM PrefixParser::guessIPFamily(string in) {
    size_t found = in.find(":");
    if (found != string::npos)
        return IP_FAM::V6;
    return IP_FAM::V4;
} /* guessIPFamily */

bool PrefixParser::splitIntoAddrAndMask(string in, string &addr, string &mask) {
    size_t pos = in.find("/");

    if (pos != string::npos && pos >= 1) {
        /* addr is now everything up until the first / */
        addr = in.substr(0, pos);
    } else if (pos == string::npos) {
        /* There is no /, so the entire input is an address */
        addr = in;
    } else {
        /* There was nothing before the /, not recoverable */
        return false;
    }

    if (pos != string::npos && pos < in.size()) {
        /* There is a / and it is not the last character.  Everything after /
         * must be the subnet.
         */
        mask = in.substr(pos + 1);
    } else if (pos != string::npos && pos == in.size()) {
        /* There is a /, but it is the last character.  This is garbage, but,
         * we may still be able to interpret the address so we will throw it
         * out.
         */
        mask = "";
    } else if (pos == string::npos) {
        /* There is no /, therefore, there is no subnet */
        mask = "";
    } else {
        /* This really shouldn't be possible because it would imply that find
         * returned a position larger than the size of the input.  Just
         * preserving sanity that mask is always initialized.
         */
        mask = "";
    }

    return true;
} /* splitIntoAddrAndMask */

int PrefixParser::parseSubnetMask(string in, IP_FAM famHint) {
    if (in.empty())
        /* Treat no subnet mask as fully qualified */
        return (famHint == IP_FAM::V6) ? 128 : 32;
    return atoi(in.c_str());
} /* parseSubnetMask */

bool PrefixParser::parseV4Addr(string in, Prefix &out) {
    struct sockaddr_in sa;

    int ret = inet_pton(AF_INET, in.c_str(), &(sa.sin_addr));

    if (ret < 0) {
        /* errno would be valid */
        return false;
    } else if (ret == 0) {
        /* input was not a valid IP address */
        return false;
    }

    /* Address in network byte order */
    out.v4Addr = htonl(sa.sin_addr.s_addr);
    return true;
} /* parseV4Addr */

bool PrefixParser::parseV6Addr(string in, Prefix &out) {
    struct sockaddr_in6 sa;

    int ret = inet_pton(AF_INET6, in.c_str(), &(sa.sin6_addr));

    if (ret < 0) {
        /* errno would be valid */
        return false;
    } else if (ret == 0) {
        /* input was not a valid IP address */
        return false;
    }

    /* Translate unsigned chars to unsigned ints to match IPA
     *
     * TODO there must be a better way to do this beyond bit fiddling
     * Maybe a Union since we've already made the assumption that the data
     * structures match?
     */
    out.v6Addr[0] = (sa.sin6_addr.s6_addr[0] << 24) |
                    (sa.sin6_addr.s6_addr[1] << 16) |
                    (sa.sin6_addr.s6_addr[2] << 8) |
                    (sa.sin6_addr.s6_addr[3]);
    out.v6Addr[1] = (sa.sin6_addr.s6_addr[4] << 24) |
                    (sa.sin6_addr.s6_addr[5] << 16) |
                    (sa.sin6_addr.s6_addr[6] << 8) |
                    (sa.sin6_addr.s6_addr[7]);
    out.v6Addr[2] = (sa.sin6_addr.s6_addr[8] << 24) |
                    (sa.sin6_addr.s6_addr[9] << 16) |
                    (sa.sin6_addr.s6_addr[10] << 8) |
                    (sa.sin6_addr.s6_addr[11]);
    out.v6Addr[3] = (sa.sin6_addr.s6_addr[12] << 24) |
                    (sa.sin6_addr.s6_addr[13] << 16) |
                    (sa.sin6_addr.s6_addr[14] << 8) |
                    (sa.sin6_addr.s6_addr[15]);
    return true;
} /* parseV6Addr */

bool PrefixParser::populateV4Mask(int mask, Prefix &out) {
    if (mask < 0 || mask > 32)
        return false;
    out.v4Mask = createMask(mask);
    return true;
} /* populateV4Mask */

bool PrefixParser::populateV6Mask(int mask, Prefix &out) {
    if (mask < 0 || mask > 128)
        return false;

    for (int i = 0; i < 4; i++) {
        out.v6Mask[i] = createMask(mask);
        mask = (mask > 32) ? mask - 32 : 0;
    }

    return true;
} /* populateV6Mask */

uint32_t PrefixParser::createMask(int mask) {
    uint32_t ret = 0;

    if (mask >= 32) {
        ret = ~ret;
        return ret;
    }

    for (int i = 0; i < 32; i++) {
        if (i < mask)
            ret = (ret << 1) | 1;
        else
            ret = (ret << 1);
    }

    return ret;
} /* createMask */

Prefix PrefixParser::makeBlankPrefix(IP_FAM famHint) {
    Prefix ret;

    ret.fam = famHint;

    ret.v4Addr = 0;
    ret.v4Mask = 0;

    ret.v6Addr[0] = 0;
    ret.v6Addr[1] = 0;
    ret.v6Addr[2] = 0;
    ret.v6Addr[3] = 0;

    ret.v6Mask[0] = 0;
    ret.v6Mask[1] = 0;
    ret.v6Mask[2] = 0;
    ret.v6Mask[3] = 0;

    return ret;
} /* makeBlankPrefix */

bool PrefixParser::isMaskValid(int mask, IP_FAM fam) {
    if (mask < 0) {
        mLastErr = "Failed parse subnet mask(" + std::to_string(mask) + ")";
        return false;
    } else if (mask == 0) {
        mLastErr = "Subnet mask cannot be 0(" + std::to_string(mask) + ")";
        return false;
    } else if (fam == IP_FAM::V4 && mask > 32) {
        mLastErr = "Interpreted address as V4 but mask was too large("
                + std::to_string(mask) + ")";
        return false;
    } else if (fam == IP_FAM::V6 && mask > 128) {
        mLastErr = "Interpreted address as V6 but mask was too large("
                + std::to_string(mask) + ")";
        return false;
    }

    return true;
} /* isMaskValid */
