// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed 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 "util/mac/mac_util.h"

#import <Foundation/Foundation.h>
#include <stdlib.h>

#include <string>

#include "base/mac/scoped_nsobject.h"
#include "base/strings/stringprintf.h"
#include "gtest/gtest.h"

#ifdef __GLIBCXX__
// When C++ exceptions are disabled, libstdc++ from GCC 4.2 defines |try| and
// |catch| so as to allow exception-expecting C++ code to build properly when
// language support for exceptions is not present. These macros interfere with
// the use of |@try| and |@catch| in Objective-C files such as this one.
// Undefine these macros here, after everything has been #included, since there
// will be no C++ uses and only Objective-C uses from this point on.
#undef try
#undef catch
#endif

namespace crashpad {
namespace test {
namespace {

// Runs /usr/bin/sw_vers with a single argument, |argument|, and places the
// command’s standard output into |output| after stripping the trailing newline.
// Fatal Google Test assertions report tool failures, which the caller should
// check for with ASSERT_NO_FATAL_FAILURE() or testing::Test::HasFatalFailure().
void SwVers(NSString* argument, std::string* output) {
  @autoreleasepool {
    base::scoped_nsobject<NSPipe> pipe([[NSPipe alloc] init]);
    base::scoped_nsobject<NSTask> task([[NSTask alloc] init]);
    [task setStandardOutput:pipe];
    [task setLaunchPath:@"/usr/bin/sw_vers"];
    [task setArguments:@[ argument ]];

    @try {
      [task launch];
    }
    @catch (NSException* exception) {
      FAIL() << [[exception name] UTF8String] << ": "
             << [[exception reason] UTF8String];
    }

    NSData* data = [[pipe fileHandleForReading] readDataToEndOfFile];
    [task waitUntilExit];

    ASSERT_EQ([task terminationReason], NSTaskTerminationReasonExit);
    ASSERT_EQ([task terminationStatus], EXIT_SUCCESS);

    output->assign(reinterpret_cast<const char*>([data bytes]), [data length]);

    EXPECT_EQ(output->at(output->size() - 1), '\n');
    output->resize(output->size() - 1);
  }
}

TEST(MacUtil, MacOSVersionComponents) {
  int major;
  int minor;
  int bugfix;
  std::string build;
  bool server;
  std::string version_string;
  ASSERT_TRUE(MacOSVersionComponents(
      &major, &minor, &bugfix, &build, &server, &version_string));

  EXPECT_GE(major, 10);
  EXPECT_LE(major, 99);
  EXPECT_GE(minor, 0);
  EXPECT_LE(minor, 99);
  EXPECT_GE(bugfix, 0);
  EXPECT_LE(bugfix, 99);

  std::string version;
  if (bugfix) {
    version = base::StringPrintf("%d.%d.%d", major, minor, bugfix);
  } else {
    // 10.x.0 releases report their version string as simply 10.x.
    version = base::StringPrintf("%d.%d", major, minor);
  }

  std::string expected_product_version;
  ASSERT_NO_FATAL_FAILURE(
      SwVers(@"-productVersion", &expected_product_version));

  EXPECT_EQ(version, expected_product_version);

  std::string expected_build_version;
  ASSERT_NO_FATAL_FAILURE(SwVers(@"-buildVersion", &expected_build_version));

  EXPECT_EQ(build, expected_build_version);

  std::string expected_product_name;
  ASSERT_NO_FATAL_FAILURE(SwVers(@"-productName", &expected_product_name));

  // Look for a space after the product name in the complete version string.
  expected_product_name += ' ';
  EXPECT_EQ(version_string.find(expected_product_name), 0u);
}

TEST(MacUtil, MacOSVersionNumber) {
  // Make sure that MacOSVersionNumber() and MacOSVersionComponents() agree. The
  // two have their own distinct implementations, and the latter was checked
  // against sw_vers above.
  int macos_version_number = MacOSVersionNumber();
  EXPECT_GE(macos_version_number, 10'00'00);
  EXPECT_LE(macos_version_number, 99'99'99);

  int major;
  int minor;
  int bugfix;
  std::string build;
  bool server;
  std::string version_string;
  ASSERT_TRUE(MacOSVersionComponents(
      &major, &minor, &bugfix, &build, &server, &version_string));

  EXPECT_EQ(macos_version_number,
            major * 1'00'00 + minor * 1'00 +
                (macos_version_number >= 10'13'04 ? bugfix : 0));
}

TEST(MacUtil, MacModelAndBoard) {
  // There’s not much that can be done to test these, so just make sure they’re
  // not empty. The model could be compared against the parsed output of
  // “system_profiler SPHardwareDataType”, but the board doesn’t show up
  // anywhere other than the I/O Registry, and that’s exactly how
  // MacModelAndBoard() gets the data, so it wouldn’t be a very useful test.
  std::string model;
  std::string board;
  MacModelAndBoard(&model, &board);

  EXPECT_FALSE(model.empty());
  EXPECT_FALSE(board.empty());
}

}  // namespace
}  // namespace test
}  // namespace crashpad
