/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "types_internal.hpp"

#include "proton/uuid.hpp"
#include "proton/types_fwd.hpp"

#include <cstdlib>
#include <ctime>
#include <sstream>
#include <iomanip>

#if defined(_WIN32)
#include <process.h>
#define GETPID _getpid
#else
#include <unistd.h>
#define GETPID getpid
#endif

namespace proton {

namespace {


// Seed the random number generated once at startup.
struct seed {
    seed() {
        // A hash of time and PID, time alone is a bad seed as programs started
        // within the same second will get the same seed.
        unsigned long secs = time(0);
        unsigned long pid = GETPID();
        std::srand(((secs*181)*((pid-83)*359))%104729);
    }
} seed_;

}

uuid uuid::copy() {
    uuid u;
    std::fill(u.begin(), u.end(), 0);
    return u;
}

uuid uuid::copy(const char* bytes) {
    uuid u;
    if (bytes)
        std::copy(bytes, bytes + u.size(), u.begin());
    else
        std::fill(u.begin(), u.end(), 0);
    return u;
}

uuid uuid::random() {
    uuid bytes;
    int r = std::rand();
    for (size_t i = 0; i < bytes.size(); ++i ) {
        bytes[i] = r & 0xFF;
        r >>= 8;
        if (!r) r = std::rand();
    }

    // From RFC4122, the version bits are set to 0100
    bytes[6] = (bytes[6] & 0x0F) | 0x40;

    // From RFC4122, the top two bits of byte 8 get set to 01
    bytes[8] = (bytes[8] & 0x3F) | 0x80;
    return bytes;
}

/// UUID standard format: 8-4-4-4-12 (36 chars, 32 alphanumeric and 4 hyphens)
std::ostream& operator<<(std::ostream& o, const uuid& u) {
    ios_guard restore_flags(o);
    o << std::hex << std::setfill('0');
    static const int segments[] = {4,2,2,2,6}; // 1 byte is 2 hex chars.
    const uint8_t *p = reinterpret_cast<const uint8_t*>(u.begin());
    for (size_t i = 0; i < sizeof(segments)/sizeof(segments[0]); ++i) {
        if (i > 0)
            o << '-';
        for (int j = 0; j < segments[i]; ++j) {
            o << std::setw(2) << printable_byte(*(p++));
        }
    }
    return o;
}

std::string uuid::str() const {
    std::ostringstream s;
    s << *this;
    return s.str();
}

}
