// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <UIKit/UIKit.h>

#include "base/debug/debugger.h"
#include "base/logging.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/mac/scoped_nsobject.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_default.h"
#include "base/test/test_suite.h"
#include "testing/coverage_util_ios.h"

// Springboard will kill any iOS app that fails to check in after launch within
// a given time. Starting a UIApplication before invoking TestSuite::Run
// prevents this from happening.

// InitIOSRunHook saves the TestSuite and argc/argv, then invoking
// RunTestsFromIOSApp calls UIApplicationMain(), providing an application
// delegate class: ChromeUnitTestDelegate. The delegate implements
// application:didFinishLaunchingWithOptions: to invoke the TestSuite's Run
// method.

// Since the executable isn't likely to be a real iOS UI, the delegate puts up a
// window displaying the app name. If a bunch of apps using MainHook are being
// run in a row, this provides an indication of which one is currently running.

static base::TestSuite* g_test_suite = NULL;
static int g_argc;
static char** g_argv;

@interface UIApplication (Testing)
- (void)_terminateWithStatus:(int)status;
@end

#if TARGET_IPHONE_SIMULATOR
// Xcode 6 introduced behavior in the iOS Simulator where the software
// keyboard does not appear if a hardware keyboard is connected. The following
// declaration allows this behavior to be overriden when the app starts up.
@interface UIKeyboardImpl
+ (instancetype)sharedInstance;
- (void)setAutomaticMinimizationEnabled:(BOOL)enabled;
- (void)setSoftwareKeyboardShownByTouch:(BOOL)enabled;
@end
#endif  // TARGET_IPHONE_SIMULATOR

@interface ChromeUnitTestDelegate : NSObject {
  base::scoped_nsobject<UIWindow> _window;
}
- (void)runTests;
@end

@implementation ChromeUnitTestDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

#if TARGET_IPHONE_SIMULATOR
  // Xcode 6 introduced behavior in the iOS Simulator where the software
  // keyboard does not appear if a hardware keyboard is connected. The following
  // calls override this behavior by ensuring that the software keyboard is
  // always shown.
  [[UIKeyboardImpl sharedInstance] setAutomaticMinimizationEnabled:NO];
  [[UIKeyboardImpl sharedInstance] setSoftwareKeyboardShownByTouch:YES];
#endif  // TARGET_IPHONE_SIMULATOR

  CGRect bounds = [[UIScreen mainScreen] bounds];

  // Yes, this is leaked, it's just to make what's running visible.
  _window.reset([[UIWindow alloc] initWithFrame:bounds]);
  [_window setBackgroundColor:[UIColor whiteColor]];
  [_window makeKeyAndVisible];

  // Add a label with the app name.
  UILabel* label = [[[UILabel alloc] initWithFrame:bounds] autorelease];
  label.text = [[NSProcessInfo processInfo] processName];
  label.textAlignment = NSTextAlignmentCenter;
  [_window addSubview:label];

  // An NSInternalInconsistencyException is thrown if the app doesn't have a
  // root view controller. Set an empty one here.
  [_window setRootViewController:[[[UIViewController alloc] init] autorelease]];

  if ([self shouldRedirectOutputToFile])
    [self redirectOutput];

  // Queue up the test run.
  [self performSelector:@selector(runTests)
             withObject:nil
             afterDelay:0.1];
  return YES;
}

// Returns true if the gtest output should be redirected to a file, then sent
// to NSLog when compleete. This redirection is used because gtest only writes
// output to stdout, but results must be written to NSLog in order to show up in
// the device log that is retrieved from the device by the host.
- (BOOL)shouldRedirectOutputToFile {
#if !TARGET_IPHONE_SIMULATOR
  return !base::debug::BeingDebugged();
#endif  // TARGET_IPHONE_SIMULATOR
  return NO;
}

// Returns the path to the directory to store gtest output files.
- (NSString*)outputPath {
  NSArray* searchPath =
      NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                          NSUserDomainMask,
                                          YES);
  CHECK([searchPath count] > 0) << "Failed to get the Documents folder";
  return [searchPath objectAtIndex:0];
}

// Returns the path to file that stdout is redirected to.
- (NSString*)stdoutPath {
  return [[self outputPath] stringByAppendingPathComponent:@"stdout.log"];
}

// Returns the path to file that stderr is redirected to.
- (NSString*)stderrPath {
  return [[self outputPath] stringByAppendingPathComponent:@"stderr.log"];
}

// Redirects stdout and stderr to files in the Documents folder in the app's
// sandbox.
- (void)redirectOutput {
  freopen([[self stdoutPath] UTF8String], "w+", stdout);
  freopen([[self stderrPath] UTF8String], "w+", stderr);
}

// Reads the redirected gtest output from a file and writes it to NSLog.
- (void)writeOutputToNSLog {
  // Close the redirected stdout and stderr files so that the content written to
  // NSLog doesn't end up in these files.
  fclose(stdout);
  fclose(stderr);
  for (NSString* path in @[ [self stdoutPath], [self stderrPath]]) {
    NSString* content = [NSString stringWithContentsOfFile:path
                                                  encoding:NSUTF8StringEncoding
                                                     error:NULL];
    NSArray* lines = [content componentsSeparatedByCharactersInSet:
        [NSCharacterSet newlineCharacterSet]];

    NSLog(@"Writing contents of %@ to NSLog", path);
    for (NSString* line in lines) {
      NSLog(@"%@", line);
    }
  }
}

- (void)runTests {
  coverage_util::ConfigureCoverageReportPath();

  int exitStatus = g_test_suite->Run();

  if ([self shouldRedirectOutputToFile])
    [self writeOutputToNSLog];

  // If a test app is too fast, it will exit before Instruments has has a
  // a chance to initialize and no test results will be seen.
  // TODO(crbug.com/137010): Figure out how much time is actually needed, and
  // sleep only to make sure that much time has elapsed since launch.
  [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];
  _window.reset();

  // Use the hidden selector to try and cleanly take down the app (otherwise
  // things can think the app crashed even on a zero exit status).
  UIApplication* application = [UIApplication sharedApplication];
  [application _terminateWithStatus:exitStatus];

  exit(exitStatus);
}

@end

namespace {

std::unique_ptr<base::MessagePump> CreateMessagePumpForUIForTests() {
  // A default MessagePump will do quite nicely in tests.
  return std::unique_ptr<base::MessagePump>(new base::MessagePumpDefault());
}

}  // namespace

namespace base {

void InitIOSTestMessageLoop() {
  MessageLoop::InitMessagePumpForUIFactory(&CreateMessagePumpForUIForTests);
}

void InitIOSRunHook(TestSuite* suite, int argc, char* argv[]) {
  g_test_suite = suite;
  g_argc = argc;
  g_argv = argv;
}

void RunTestsFromIOSApp() {
  // When TestSuite::Run is invoked it calls RunTestsFromIOSApp(). On the first
  // invocation, this method fires up an iOS app via UIApplicationMain. Since
  // UIApplicationMain does not return until the app exits, control does not
  // return to the initial TestSuite::Run invocation, so the app invokes
  // TestSuite::Run a second time and since |ran_hook| is true at this point,
  // this method is a no-op and control returns to TestSuite:Run so that test
  // are executed. Once the app exits, RunTestsFromIOSApp calls exit() so that
  // control is not returned to the initial invocation of TestSuite::Run.
  static bool ran_hook = false;
  if (!ran_hook) {
    ran_hook = true;
    mac::ScopedNSAutoreleasePool pool;
    int exit_status = UIApplicationMain(g_argc, g_argv, nil,
                                        @"ChromeUnitTestDelegate");
    exit(exit_status);
  }
}

}  // namespace base
