#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <systemd/sd-bus.h>

/* Dbus settings to get the DNS entries updated in resolv.conf */
const char *bus_name = "org.openbmc.NetworkManager";
const char *object_path = "/org/openbmc/NetworkManager/Interface";
const char *intf_name = "org.openbmc.NetworkManager";

/* Used to tell Network Manager that Name Server listing is coming from DHCP */
const char *DHCP_MARKER = "DHCP_AUTO= ";

#define DHCP_MARKER_LEN strlen(DHCP_MARKER)

/*
 * ----------------------------------------------
 *  Receives the buffer that has the IPs of DNS
 *  and then makes a dbus call to have these DNS
 *  entries updated in /etc/resolv.conf
 *  --------------------------------------------
 */
int update_resolv_conf(const char *dns_entry)
{
    /* To read the message sent by dbus handler */
    const char *resp_msg = NULL;

    /* Generic error handler */
    int rc = 0;

    if(dns_entry == NULL || !(strlen(dns_entry)))
    {
        fprintf(stderr,"Invalid DNS entry\n");
        return -1;
    }

    /*
     * Since 'state' file gets touched many a times during the network setting,
     * it does not make sense to  have the same DNS entry updated in
     * resolv.conf. SO we can actually have a cache of what was previously
     * updated and not update if the same DNS info is supplied again.
     * Eventhough this approach is a gain performance wise, it will
     * open up windows. Assume a case where DHCP has given 1.2.3.4 as IP and
     * user goes and updates the DNS as 4.5.6.7 and then user restarts the
     * network and thus getting the value of 1.2.3.4. If we maintain a cache of
     * what was previously updated, since we get 1.2.3.4 again, we will not
     * update with 1.2.3.4 eventhough that is needed since 4.5.6.7 would not
     * make sense. So doing updates to resolv.conf each time is bit of a
     * overkill but its error proof.
     */

    /* Encapsulated respose by dbus handler */
    sd_bus_message *response = NULL;

    /* Errors reported by dbus handler */
    sd_bus_error bus_error = SD_BUS_ERROR_NULL;

    /*
     * Gets a hook onto SYSTEM bus. This API may get called multiple
     * times so do not want to have so many instances of bus as it
     * leads to system resource issues. Re use the one that is present.
     */
    static sd_bus *bus_type = NULL;
    if(bus_type == NULL)
    {
        rc = sd_bus_open_system(&bus_type);
        if(rc < 0)
        {
            fprintf(stderr,"Error:[%s] getting system bus\n",strerror(-rc));
            return rc;
        }
    }

    rc = sd_bus_call_method(
                            bus_type,        /* In the System Bus */
                            bus_name,        /* Service to contact */
                            object_path,     /* Object path */
                            intf_name,       /* Interface name */
                            "SetNameServers",/* Method to be called */
                            &bus_error,      /* object to return error */
                            &response,       /* Response buffer if any */
                            "s",             /* Input as strings */
                            dns_entry,       /* string of DNS IPs */
                            NULL);           /* No return message expected */
    if(rc < 0)
    {
        fprintf(stderr,"ERROR updating DNS entries:[%s]\n",bus_error.message);
        goto finish;
    }

    /* Extract the encapsulated response message */
    rc = sd_bus_message_read(response, "s", &resp_msg);
    if (rc < 0)
    {
        fprintf(stderr,"Error:[%s] reading dns"
                " updation status\n",strerror(-rc));
    }
    else
    {
        printf("%s\n",resp_msg);
    }

finish:
    sd_bus_error_free(&bus_error);
    response = sd_bus_message_unref(response);

    return rc;
}

/*
 * ----------------------------------------------
 *  Gets invoked by inotify handler whenever the
 *  netif/state file gets modified
 *  -or- when this binary first gets launched.
 *  --------------------------------------------
 */
int read_netif_state_file(const char *netif_dir, const char *state_file)
{
    FILE *fp;

    /* Each line read from 'state' file */
    char *line = NULL;

    /* A list containing all the DNS IPs that are mentioned in 'state' file. */
    char *dns_list = NULL;

    /* length of each line read from 'state' file */
    size_t len = 0;

    /* Length of current and updated dns list */
    size_t list_len = 0;
    size_t new_list_len = 0;

    /* Generic error reporter */
    int rc = 0;

    /* Extract the 'state' file */
    char netif_state_file[strlen(netif_dir) + strlen(state_file) + 2];
    sprintf(netif_state_file,"%s%s", netif_dir,state_file);

    fp = fopen(netif_state_file,"r");
    if(fp == NULL)
    {
        fprintf(stderr,"Error opening[%s]\n",netif_state_file);
        return -1;
    }

    /*
     * Read the file line by line and look for the one that starts with DNS
     * If there is one, then what appears after DNS= are the IPs of the DNS
     * Just checking for DNS here since any non standard IP is rejected by
     * the dbus handler. This is to cater to cases where file may have DNS =
     */
    while ((getline(&line, &len, fp)) != -1)
    {
        if(!(strncmp(line,"DNS",3)))
        {
            /* Go all the way until the start of IPs */
            char *dns_entry = strrchr(line, '=');

            /* Advance to the first character after = */
            dns_entry = &((char *)dns_entry)[1];

            /* If we have never populated anything into the list */
            if(dns_list == NULL)
            {
                /* The extra 2 characters to leave some gaps between DNS
                 * entries that would come from multiple lines since each line
                 * would start with DNS= and this overlaps with previous DNS IP.
                 * Although I don't see this as any reality to have DNS IPs
                 * spreading multiple lines.
                 */
                list_len = strlen(dns_entry) + DHCP_MARKER_LEN + 2;
                dns_list = (char *)malloc(list_len);

                /*
                 * Populate DHCP_AUTO= along with the first line of DNS entries
                 * This will help in putting the appropriate comments in
                 * /etc/resolv.conf indicating the mode of DNS setting.
                 */
                memset(dns_list, ' ', list_len);
                memcpy(dns_list, DHCP_MARKER, DHCP_MARKER_LEN);
                memcpy(&dns_list[DHCP_MARKER_LEN], dns_entry, strlen(dns_entry));
                dns_list[list_len]='\0';
            }
            else
            {
                /* This would be the entries that are coming from second+ line */
                new_list_len = strlen(dns_entry) + list_len + 2;
                dns_list = (char *)realloc(dns_list, new_list_len);

                memset(&dns_list[list_len], ' ', strlen(dns_entry) + 2);
                memmove(&dns_list[list_len], dns_entry, strlen(dns_entry));

                /* Starting offset for next line */
                list_len = new_list_len;
                dns_list[list_len] = '\0';
            }
        }

        /* Memory is allocated by getline and user needs to free */
        if(line)
        {
            free(line);
            line = NULL;
        }
    }

    /* If we have found some or more DNS entries */
    if(dns_list)
    {
        /*
         * Being extra cautious if string somehow is not null terminated in the loop
         */
        dns_list[list_len] = '\0';

        rc = update_resolv_conf(dns_list);
        if(rc < 0)
        {
            fprintf(stderr,"Error updating resolv.conf with:[%s]\n",dns_list);
        }

        free(dns_list);
        dns_list = NULL;
    }

    return 0;
}

void usage(void)
{
    printf("Usage: netman_watch_dns <Absolute path of DHCP netif state file>\n"
            "Example: netman_watch_dns /run/systemd/netif/state\n");
    return;
}

/*
 * ------------------------------------------------------
 *  Registers a inotify watch on the state file and calls
 *  into handling the state file whenever there is a change.
 * ------------------------------------------------------
 */
int watch_for_dns_change(char *netif_dir, char *state_file)
{
    int inotify_fd, wd;

    /* the aligned statement below is per the recommendation by inotify(7) */
    char event_data[4096]
        __attribute__ ((aligned(__alignof__(struct inotify_event))));

    /* To check the number of bytes read from inotify event */
    ssize_t bytes_read = 0;

    /* To walk event by event when inotify returns */
    char *ptr = NULL;

    /* Variable to hold individual event notification */
    const struct inotify_event *event = NULL;

    /* Generic error handler */
    int rc = 0;

    /* Create inotify instance */
    inotify_fd = inotify_init();
    if(inotify_fd == -1)
    {
        fprintf(stderr,"Error:[%s] initializing Inotify",strerror(errno));
        return -1;
    }

    /* Register to write actions on the netif directory */
    wd = inotify_add_watch(inotify_fd, netif_dir, IN_MODIFY);
    if(wd == -1)
    {
        fprintf(stderr,"Error:[%s] adding watch for:[%s]\n",
                strerror(errno), netif_dir);
        return -1;
    }

    /*
     * When this is first launched, we need to go see
     * if there is anything present in the state file.
     * Doing it here to close any gaps between the file
     * getting created before registering inotifier.
     */
    rc = read_netif_state_file(netif_dir, state_file);
    if(rc < 0)
    {
        fprintf(stderr,"Error doing initial processing of state file\n");
    }

    /* Read events forever */
    for (;;)
    {
        memset(event_data, 0x0, sizeof(event_data));
        bytes_read = read(inotify_fd, event_data, sizeof(event_data));
        if(bytes_read <= 0)
        {
            fprintf(stderr,"event_data read from inotify fd was Invalid\n");
            continue;
        }

        /* Process all of the events in buffer returned by read() */
        for(ptr = event_data; ptr < event_data + bytes_read;
            ptr += sizeof(struct inotify_event) + event->len)
        {
            event = (struct inotify_event *)ptr;

            /*
             * We are not interested in anything other than updates to
             * state file. Now when this code is being written, its in
             * /run/systemd/netif/state.
             */
            if((event->len > 0) && (strstr(event->name, state_file)))
            {
                rc = read_netif_state_file(netif_dir, state_file);
                if(rc < 0)
                {
                    fprintf(stderr,"Error processing inotify event\n");
                }
            }
        } /* Processing all inotify events. */
    } /* Endless loop waiting for events. */

    /*
     * Technically, we should not reach here since the monitor function
     * is not supposed to stop even on error. But for completeness.....
     */
    inotify_rm_watch(inotify_fd, wd);
    close(inotify_fd);

    return 0;
}

int main(int argc, char *argv[])
{
    /* Generic error handler */
    int rc = 0;

    /* Sanity checking */
    if(argc != 2 || argv[1] == NULL)
    {
        usage();
        return -1;
    }

    /*
     * We now have the job of extracting the directory and
     * the state file from the user supplied input.
     */
    char netif_dir[strlen(argv[1]) + 1];
    memset(netif_dir, 0x0, sizeof(netif_dir));

    /* File where the actual DNS= entry is found */
    char *state_file = NULL;

    /* Filter invalid inputs */
    state_file = strrchr(argv[1], '/');
    if(strlen(state_file) <= 1)
    {
        fprintf(stderr,"Invalid state file :[%s] specified\n",state_file);
        return -1;
    }
    else
    {
        /* we have /state now and what we need is just the 'state' */
        state_file = &((char *)state_file)[1];

        /*
         * Also extract the Absolute Path of the directory
         * containing this state file
         */
        strncpy(netif_dir, argv[1], strlen(argv[1]) - strlen(state_file));
        strcat(netif_dir,"\0");
    }

    printf("Watching for changes in DNS settings..\n");

     /* Commenting since this functionality has been built into network
      * manager and this file will be deleted in the very next commit
      */
    /*
    rc = watch_for_dns_change(netif_dir, state_file);
    if(rc < 0)
    {
        fprintf(stderr,"Error watching for DNS changes\n");
    }
    */

    // Returning will result in app getting launched again per Restart
    // policy in service file
    pause();

    return rc;
}
