/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "alloc-util.h"
#include "macro.h"
#include "sort-util.h"
#include "uid-range.h"
#include "user-util.h"

static bool uid_range_intersect(UidRange *range, uid_t start, uid_t nr) {
        assert(range);

        return range->start <= start + nr &&
                range->start + range->nr >= start;
}

static void uid_range_coalesce(UidRange **p, unsigned *n) {
        assert(p);
        assert(n);

        for (unsigned i = 0; i < *n; i++) {
                for (unsigned j = i + 1; j < *n; j++) {
                        UidRange *x = (*p)+i, *y = (*p)+j;

                        if (uid_range_intersect(x, y->start, y->nr)) {
                                uid_t begin, end;

                                begin = MIN(x->start, y->start);
                                end = MAX(x->start + x->nr, y->start + y->nr);

                                x->start = begin;
                                x->nr = end - begin;

                                if (*n > j+1)
                                        memmove(y, y+1, sizeof(UidRange) * (*n - j -1));

                                (*n)--;
                                j--;
                        }
                }
        }
}

static int uid_range_compare(const UidRange *a, const UidRange *b) {
        int r;

        r = CMP(a->start, b->start);
        if (r != 0)
                return r;

        return CMP(a->nr, b->nr);
}

int uid_range_add(UidRange **p, unsigned *n, uid_t start, uid_t nr) {
        bool found = false;
        UidRange *x;

        assert(p);
        assert(n);

        if (nr <= 0)
                return 0;

        for (unsigned i = 0; i < *n; i++) {
                x = (*p) + i;
                if (uid_range_intersect(x, start, nr)) {
                        found = true;
                        break;
                }
        }

        if (found) {
                uid_t begin, end;

                begin = MIN(x->start, start);
                end = MAX(x->start + x->nr, start + nr);

                x->start = begin;
                x->nr = end - begin;
        } else {
                UidRange *t;

                t = reallocarray(*p, *n + 1, sizeof(UidRange));
                if (!t)
                        return -ENOMEM;

                *p = t;
                x = t + ((*n) ++);

                x->start = start;
                x->nr = nr;
        }

        typesafe_qsort(*p, *n, uid_range_compare);
        uid_range_coalesce(p, n);

        return *n;
}

int uid_range_add_str(UidRange **p, unsigned *n, const char *s) {
        uid_t start, nr;
        const char *t;
        int r;

        assert(p);
        assert(n);
        assert(s);

        t = strchr(s, '-');
        if (t) {
                char *b;
                uid_t end;

                b = strndupa(s, t - s);
                r = parse_uid(b, &start);
                if (r < 0)
                        return r;

                r = parse_uid(t+1, &end);
                if (r < 0)
                        return r;

                if (end < start)
                        return -EINVAL;

                nr = end - start + 1;
        } else {
                r = parse_uid(s, &start);
                if (r < 0)
                        return r;

                nr = 1;
        }

        return uid_range_add(p, n, start, nr);
}

int uid_range_next_lower(const UidRange *p, unsigned n, uid_t *uid) {
        uid_t closest = UID_INVALID, candidate;

        assert(p);
        assert(uid);

        candidate = *uid - 1;

        for (unsigned i = 0; i < n; i++) {
                uid_t begin, end;

                begin = p[i].start;
                end = p[i].start + p[i].nr - 1;

                if (candidate >= begin && candidate <= end) {
                        *uid = candidate;
                        return 1;
                }

                if (end < candidate)
                        closest = end;
        }

        if (closest == UID_INVALID)
                return -EBUSY;

        *uid = closest;
        return 1;
}

bool uid_range_contains(const UidRange *p, unsigned n, uid_t uid) {
        assert(p);
        assert(uid);

        for (unsigned i = 0; i < n; i++)
                if (uid >= p[i].start && uid < p[i].start + p[i].nr)
                        return true;

        return false;
}
