/*
 * Copyright (C) 2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS 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.
 */

#import "config.h"
#import "DaemonTestUtilities.h"

#if PLATFORM(MAC) || PLATFORM(IOS)

#import <mach-o/dyld.h>
#import <wtf/Vector.h>

NS_ASSUME_NONNULL_BEGIN

#if PLATFORM(IOS)
@interface NSTask : NSObject
- (instancetype)init;
- (void)launch;
- (void)waitUntilExit;

@property (nullable, copy) NSString *launchPath;
@property (nullable, copy) NSArray<NSString *> *arguments;
@property (nullable, retain) id standardOutput;
@property (readonly, getter=isRunning) BOOL running;
@end
#endif

namespace TestWebKitAPI {

static RetainPtr<NSURL> currentExecutableLocation()
{
    uint32_t size { 0 };
    _NSGetExecutablePath(nullptr, &size);
    Vector<char> buffer;
    buffer.resize(size + 1);
    _NSGetExecutablePath(buffer.data(), &size);
    buffer[size] = '\0';
    auto pathString = adoptNS([[NSString alloc] initWithUTF8String:buffer.data()]);
    return adoptNS([[NSURL alloc] initFileURLWithPath:pathString.get() isDirectory:NO]);
}

RetainPtr<NSURL> currentExecutableDirectory()
{
    return [currentExecutableLocation() URLByDeletingLastPathComponent];
}

#if HAVE(OS_LAUNCHD_JOB)

void registerPlistWithLaunchD(RetainPtr<xpc_object_t>&& plist)
{
    NSError *error = nil;
    auto launchDJob = adoptNS([[OSLaunchdJob alloc] initWithPlist:plist.get()]);
    [launchDJob submit:&error];

    // In the iOS Simulator we often see the following error here:
    // Error Domain=OSLaunchdErrorDomain Code=17 "File exists"
    // Tests still behave as expected.
#if PLATFORM(MAC)
    EXPECT_FALSE(error);
#endif
}

#else // HAVE(OS_LAUNCHD_JOB)

void registerPlistWithLaunchD(RetainPtr<NSDictionary>&& plist, NSURL *tempDir)
{
    NSError *error = nil;
    NSURL *plistLocation = [tempDir URLByAppendingPathComponent:@"DaemonInfo.plist"];
    BOOL success = [[NSFileManager defaultManager] createDirectoryAtURL:tempDir withIntermediateDirectories:YES attributes:nil error:&error];
    EXPECT_TRUE(success);
    EXPECT_FALSE(error);
    success = [plist writeToURL:plistLocation error:&error];
    EXPECT_TRUE(success);
    system([NSString stringWithFormat:@"launchctl unload %@ 2> /dev/null", plistLocation.path].fileSystemRepresentation);
    system([NSString stringWithFormat:@"launchctl load %@", plistLocation.path].fileSystemRepresentation);
    EXPECT_FALSE(error);
}

#endif // HAVE(OS_LAUNCHD_JOB)

static int pidOfFirstDaemonInstance(NSString *daemonExecutableName)
{
    auto task = adoptNS([[NSTask alloc] init]);
    task.get().launchPath = @"/bin/ps";
    task.get().arguments = @[
        @"-ax",
        @"-o",
        @"pid,comm"
    ];

    auto taskPipe = adoptNS([[NSPipe alloc] init]);
    [task setStandardOutput:taskPipe.get()];
    [task launch];

    auto data = adoptNS([[NSMutableData alloc] init]);
    while ([task isRunning])
        [data appendData:[[taskPipe fileHandleForReading] readDataToEndOfFile]];
    [data appendData:[[taskPipe fileHandleForReading] readDataToEndOfFile]];

    auto psString = adoptNS([[NSString alloc] initWithData:data.get() encoding:NSUTF8StringEncoding]);
    NSArray<NSString *> *psEntries = [psString componentsSeparatedByString:@"\n"];

    for (NSString* entry in psEntries) {
        if (![entry hasSuffix:daemonExecutableName])
            continue;
        NSArray<NSString *> *components = [entry componentsSeparatedByString:@" "];
        EXPECT_GE([components count], 2u);
        return [[components firstObject] integerValue];
    }

    return 0;
}

void killFirstInstanceOfDaemon(NSString *daemonExecutableName)
{
    auto pid = pidOfFirstDaemonInstance(daemonExecutableName);
    if (!pid)
        return;

    auto task = adoptNS([[NSTask alloc] init]);
    task.get().launchPath = @"/bin/kill";
    task.get().arguments = @[
        @"-9",
        [@(pid) stringValue]
    ];

    [task launch];
    [task waitUntilExit];
}

} // namespace TestWebKitAPI

NS_ASSUME_NONNULL_END

#endif // PLATFORM(MAC) || PLATFORM(IOS)
