/*
 * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "splashscreen_impl.h"

#import <Cocoa/Cocoa.h>
#import <objc/objc-auto.h>

#include <Security/AuthSession.h>
#import "NSApplicationAWT.h"

#include <sys/time.h>
#include <pthread.h>
#include <iconv.h>
#include <langinfo.h>
#include <locale.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <dlfcn.h>

#include <sizecalc.h>
#import "ThreadUtilities.h"

NSString* findScaledImageName(NSString *fileName,
                              NSUInteger dotIndex,
                              NSString *strToAppend);

static NSScreen* SplashNSScreen()
{
    return [[NSScreen screens] objectAtIndex: 0];
}

static void SplashCenter(Splash * splash)
{
    NSRect screenFrame = [SplashNSScreen() frame];

    splash->x = (screenFrame.size.width - splash->width) / 2;
    splash->y = (screenFrame.size.height - splash->height) / 2 + screenFrame.origin.y;
}

unsigned
SplashTime(void) {
    struct timeval tv;
    struct timezone tz;
    unsigned long long msec;

    gettimeofday(&tv, &tz);
    msec = (unsigned long long) tv.tv_sec * 1000 +
        (unsigned long long) tv.tv_usec / 1000;

    return (unsigned) msec;
}

/* Could use npt but decided to cut down on linked code size */
char* SplashConvertStringAlloc(const char* in, int* size) {
    const char     *codeset;
    const char     *codeset_out;
    iconv_t         cd;
    size_t          rc;
    char           *buf = NULL, *out;
    size_t          bufSize, inSize, outSize;
    const char* old_locale;

    if (!in) {
        return NULL;
    }
    old_locale = setlocale(LC_ALL, "");

    codeset = nl_langinfo(CODESET);
    if ( codeset == NULL || codeset[0] == 0 ) {
        goto done;
    }
    /* we don't need BOM in output so we choose native BE or LE encoding here */
    codeset_out = (platformByteOrder()==BYTE_ORDER_MSBFIRST) ?
        "UCS-2BE" : "UCS-2LE";

    cd = iconv_open(codeset_out, codeset);
    if (cd == (iconv_t)-1 ) {
        goto done;
    }
    inSize = strlen(in);
    buf = SAFE_SIZE_ARRAY_ALLOC(malloc, inSize, 2);
    if (!buf) {
        return NULL;
    }
    bufSize = inSize*2; // need 2 bytes per char for UCS-2, this is
                        // 2 bytes per source byte max
    out = buf; outSize = bufSize;
    /* linux iconv wants char** source and solaris wants const char**...
       cast to void* */
    rc = iconv(cd, (void*)&in, &inSize, &out, &outSize);
    iconv_close(cd);

    if (rc == (size_t)-1) {
        free(buf);
        buf = NULL;
    } else {
        if (size) {
            *size = (bufSize-outSize)/2; /* bytes to wchars */
        }
    }
done:
    setlocale(LC_ALL, old_locale);
    return buf;
}

BOOL isSWTRunning() {
    char envVar[80];
    // If this property is present we are running SWT
    snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
    return getenv(envVar) != NULL;
}

jboolean SplashGetScaledImageName(const char* jar, const char* file,
                                  float *scaleFactor, char *scaledFile,
                                  const size_t scaledImageLength) {
    *scaleFactor = 1;

    if(isSWTRunning()){
        return JNI_FALSE;
    }

    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    __block float screenScaleFactor = 1;

    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        // initialize NSApplication and AWT stuff
        [NSApplicationAWT sharedApplication];
        screenScaleFactor = [SplashNSScreen() backingScaleFactor];
    }];

    if (screenScaleFactor > 1) {
        NSString *fileName = [NSString stringWithUTF8String: file];
        NSUInteger length = [fileName length];
        NSRange range = [fileName rangeOfString: @"."
                                        options:NSBackwardsSearch];
        NSUInteger dotIndex = range.location;
        NSString *fileName2x = nil;

        fileName2x = findScaledImageName(fileName, dotIndex, @"@2x");
        if(![[NSFileManager defaultManager]
                fileExistsAtPath: fileName2x]) {
            fileName2x = findScaledImageName(fileName, dotIndex, @"@200pct");
        }
        if (jar || [[NSFileManager defaultManager]
                fileExistsAtPath: fileName2x]){
            if (strlen([fileName2x UTF8String]) > scaledImageLength) {
                [pool drain];
                return JNI_FALSE;
            }
            *scaleFactor = 2;
            strcpy(scaledFile, [fileName2x UTF8String]);
            [pool drain];
            return JNI_TRUE;
        }
    }
    [pool drain];
    return JNI_FALSE;
}

static int isInAquaSession() {
    // environment variable to bypass the aqua session check
    char *ev = getenv("AWT_FORCE_HEADFUL");
    if (ev && (strncasecmp(ev, "true", 4) == 0)) {
        // if "true" then tell the caller we're in
        // an Aqua session without actually checking
        return 1;
    }
    // Is the WindowServer available?
    SecuritySessionId session_id;
    SessionAttributeBits session_info;
    OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
    if (status == noErr) {
        if (session_info & sessionHasGraphicAccess) {
            return 1;
        }
    }
    return 0;
}

int
SplashInitPlatform(Splash * splash) {
    if (!isInAquaSession()) {
        return 0;
    }
    pthread_mutex_init(&splash->lock, NULL);

    splash->maskRequired = 0;


    //TODO: the following is too much of a hack but should work in 90% cases.
    //      besides we don't use device-dependent drawing, so probably
    //      that's very fine indeed
    splash->byteAlignment = 1;
    initFormat(&splash->screenFormat, 0xff << 8,
            0xff << 16, 0xff << 24, 0xff << 0);
    splash->screenFormat.byteOrder = 1 ?  BYTE_ORDER_LSBFIRST : BYTE_ORDER_MSBFIRST;
    splash->screenFormat.depthBytes = 4;

    // If we are running SWT we should not start a runLoop
    if (!isSWTRunning()) {
        [ThreadUtilities performOnMainThreadWaiting:NO block:^() {
            [NSApplicationAWT runAWTLoopWithApp:[NSApplicationAWT sharedApplication]];
        }];
    }
    return 1;
}

void
SplashCleanupPlatform(Splash * splash) {
    splash->maskRequired = 0;
}

void
SplashDonePlatform(Splash * splash) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    pthread_mutex_destroy(&splash->lock);
    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        if (splash->window) {
            [splash->window orderOut:nil];
            [splash->window release];
        }
    }];
    [pool drain];
}

void
SplashLock(Splash * splash) {
    pthread_mutex_lock(&splash->lock);
}

void
SplashUnlock(Splash * splash) {
    pthread_mutex_unlock(&splash->lock);
}

void
SplashInitFrameShape(Splash * splash, int imageIndex) {
    // No shapes, we rely on alpha compositing
}

void * SplashScreenThread(void *param);
void
SplashCreateThread(Splash * splash) {
    pthread_t thr;
    pthread_attr_t attr;

    int rslt = pthread_attr_init(&attr);
    if (rslt != 0) return;
    rslt = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash);
    if (rslt != 0) {
        fprintf(stderr, "Could not create SplashScreen thread, error number:%d\n", rslt);
    }
    pthread_attr_destroy(&attr);
}

void
SplashRedrawWindow(Splash * splash) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        // drop the reference to the old view and image
        [splash->window setContentView: nil];
        SplashUpdateScreenData(splash);

        // NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
        NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
            initWithBitmapDataPlanes: (unsigned char**)&splash->screenData
                          pixelsWide: splash->width
                          pixelsHigh: splash->height
                       bitsPerSample: 8
                     samplesPerPixel: 4
                            hasAlpha: YES
                            isPlanar: NO
                      colorSpaceName: NSDeviceRGBColorSpace
                        bitmapFormat: NSAlphaFirstBitmapFormat | NSAlphaNonpremultipliedBitmapFormat
                         bytesPerRow: splash->width * 4
                        bitsPerPixel: 32];

        NSImage * image = [[NSImage alloc]
            initWithSize: NSMakeSize(splash->width, splash->height)];
        [image setBackgroundColor: [NSColor clearColor]];

        [image addRepresentation: rep];
        float scaleFactor = splash->scaleFactor;
        if (scaleFactor > 0 && scaleFactor != 1) {
            NSSize size = [image size];
            size.width /= scaleFactor;
            size.height /= scaleFactor;
            [image setSize: size];
        }

        NSImageView * view = [[NSImageView alloc] init];

        [view setImage: image];
        [view setEditable: NO];
        //NOTE: we don't set a 'wait cursor' for the view because:
        //      1. The Cocoa GUI guidelines suggest to avoid it, and use a progress
        //         bar instead.
        //      2. There simply isn't an instance of NSCursor that represent
        //         the 'wait cursor'. So that is undoable.

        //TODO: only the first image in an animated gif preserves transparency.
        //      Looks like the splash->screenData contains inappropriate data
        //      for all but the first frame.

        [image release];
        [rep release];

        [splash->window setContentView: view];
        [splash->window orderFrontRegardless];
    }];

    [pool drain];
}

void SplashReconfigureNow(Splash * splash) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        SplashCenter(splash);

        if (!splash->window) {
            return;
        }

        [splash->window orderOut:nil];
        [splash->window setFrame: NSMakeRect(splash->x, splash->y, splash->width, splash->height)
                         display: NO];
    }];

    [pool drain];

    SplashRedrawWindow(splash);
}

void
SplashEventLoop(Splash * splash) {

    /* we should have splash _locked_ on entry!!! */

    while (1) {
        struct pollfd pfd[1];
        int timeout = -1;
        int ctl = splash->controlpipe[0];
        int rc;
        int pipes_empty;

        pfd[0].fd = ctl;
        pfd[0].events = POLLIN | POLLPRI;

        errno = 0;
        if (splash->isVisible>0 && SplashIsStillLooping(splash)) {
            timeout = splash->time + splash->frames[splash->currentFrame].delay
                - SplashTime();
            if (timeout < 0) {
                timeout = 0;
            }
        }
        SplashUnlock(splash);
        rc = poll(pfd, 1, timeout);
        SplashLock(splash);
        if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
                SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
            SplashNextFrame(splash);
            SplashRedrawWindow(splash);
        }
        if (rc <= 0) {
            errno = 0;
            continue;
        }
        pipes_empty = 0;
        while(!pipes_empty) {
            char buf;

            pipes_empty = 1;
            if (read(ctl, &buf, sizeof(buf)) > 0) {
                pipes_empty = 0;
                switch (buf) {
                case SPLASHCTL_UPDATE:
                    if (splash->isVisible>0) {
                        SplashRedrawWindow(splash);
                    }
                    break;
                case SPLASHCTL_RECONFIGURE:
                    if (splash->isVisible>0) {
                        SplashReconfigureNow(splash);
                    }
                    break;
                case SPLASHCTL_QUIT:
                    return;
                }
            }
        }
    }
}

void *
SplashScreenThread(void *param) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Splash *splash = (Splash *) param;

    SplashLock(splash);
    pipe(splash->controlpipe);
    fcntl(splash->controlpipe[0], F_SETFL,
        fcntl(splash->controlpipe[0], F_GETFL, 0) | O_NONBLOCK);
    splash->time = SplashTime();
    splash->currentFrame = 0;
    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        SplashCenter(splash);

        splash->window = (void*) [[NSWindow alloc]
            initWithContentRect: NSMakeRect(splash->x, splash->y, splash->width, splash->height)
                      styleMask: NSWindowStyleMaskBorderless
                        backing: NSBackingStoreBuffered
                          defer: NO
                         screen: SplashNSScreen()];

        [splash->window setOpaque: NO];
        [splash->window setBackgroundColor: [NSColor clearColor]];
    }];
    fflush(stdout);
    if (splash->window) {
        [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
            [splash->window orderFrontRegardless];
        }];
        SplashRedrawWindow(splash);
        SplashEventLoop(splash);
    }
    SplashUnlock(splash);
    SplashDone(splash);

    splash->isVisible=-1;

    [pool drain];

    return 0;
}

void
sendctl(Splash * splash, char code) {
    if (splash && splash->controlpipe[1]) {
        write(splash->controlpipe[1], &code, 1);
    }
}

void
SplashClosePlatform(Splash * splash) {
    sendctl(splash, SPLASHCTL_QUIT);
}

void
SplashUpdate(Splash * splash) {
    sendctl(splash, SPLASHCTL_UPDATE);
}

void
SplashReconfigure(Splash * splash) {
    sendctl(splash, SPLASHCTL_RECONFIGURE);
}

NSString* findScaledImageName(NSString *fileName, NSUInteger dotIndex, NSString *strToAppend) {
    NSString *fileName2x = nil;
    if (dotIndex == NSNotFound) {
        fileName2x = [fileName stringByAppendingString: strToAppend];
    } else {
        fileName2x = [fileName substringToIndex: dotIndex];
        fileName2x = [fileName2x stringByAppendingString: strToAppend];
        fileName2x = [fileName2x stringByAppendingString:
                      [fileName substringFromIndex: dotIndex]];
    }
    return fileName2x;
}

