// 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/net/http_transport.h"

#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <sys/utsname.h>

#include "base/mac/foundation_util.h"
#import "base/mac/scoped_nsobject.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "build/build_config.h"
#include "package.h"
#include "third_party/apple_cf/CFStreamAbstract.h"
#include "util/file/file_io.h"
#include "util/misc/implicit_cast.h"
#include "util/net/http_body.h"

namespace crashpad {

namespace {

NSString* AppendEscapedFormat(NSString* base,
                              NSString* format,
                              NSString* data) {
  return [base stringByAppendingFormat:
                   format,
                   [data stringByAddingPercentEncodingWithAllowedCharacters:
                             [[NSCharacterSet
                                 characterSetWithCharactersInString:
                                     @"()<>@,;:\\\"/[]?={} \t"] invertedSet]]];
}

// This builds the same User-Agent string that CFNetwork would build internally,
// but it uses PACKAGE_NAME and PACKAGE_VERSION in place of values obtained from
// the main bundle’s Info.plist.
NSString* UserAgentString() {
  NSString* user_agent = [NSString string];

  // CFNetwork would use the main bundle’s CFBundleName, or the main
  // executable’s filename if none.
  user_agent = AppendEscapedFormat(user_agent, @"%@", @PACKAGE_NAME);

  // CFNetwork would use the main bundle’s CFBundleVersion, or the string
  // “(unknown version)” if none.
  user_agent = AppendEscapedFormat(user_agent, @"/%@", @PACKAGE_VERSION);

  // Expected to be CFNetwork.
  NSBundle* nsurl_bundle = [NSBundle bundleForClass:[NSURLRequest class]];
  NSString* bundle_name = base::mac::ObjCCast<NSString>([nsurl_bundle
      objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleNameKey)]);
  if (bundle_name) {
    user_agent = AppendEscapedFormat(user_agent, @" %@", bundle_name);

    NSString* bundle_version = base::mac::ObjCCast<NSString>([nsurl_bundle
        objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleVersionKey)]);
    if (bundle_version) {
      user_agent = AppendEscapedFormat(user_agent, @"/%@", bundle_version);
    }
  }

  utsname os;
  if (uname(&os) != 0) {
    PLOG(WARNING) << "uname";
  } else {
    user_agent = AppendEscapedFormat(user_agent, @" %@", @(os.sysname));
    user_agent = AppendEscapedFormat(user_agent, @"/%@", @(os.release));

    // CFNetwork just uses the equivalent of os.machine to obtain the native
    // (kernel) architecture. Here, give the process’ architecture as well as
    // the native architecture. Use the same strings that the kernel would, so
    // that they can be de-duplicated.
#if defined(ARCH_CPU_X86)
    NSString* arch = @"i386";
#elif defined(ARCH_CPU_X86_64)
    NSString* arch = @"x86_64";
#elif defined(ARCH_CPU_ARM64)
    NSString* arch = @"arm64";
#else
#error Port
#endif
    user_agent = AppendEscapedFormat(user_agent, @" (%@", arch);

    NSString* machine = @(os.machine);
    if (![machine isEqualToString:arch]) {
      user_agent = AppendEscapedFormat(user_agent, @"; %@", machine);
    }

    user_agent = [user_agent stringByAppendingString:@")"];
  }

  return user_agent;
}

// An implementation of CFReadStream. This implements the V0 callback
// scheme.
class HTTPBodyStreamCFReadStream {
 public:
  explicit HTTPBodyStreamCFReadStream(HTTPBodyStream* body_stream)
      : body_stream_(body_stream) {
  }

  HTTPBodyStreamCFReadStream(const HTTPBodyStreamCFReadStream&) = delete;
  HTTPBodyStreamCFReadStream& operator=(const HTTPBodyStreamCFReadStream&) =
      delete;

  // Creates a new NSInputStream, which the caller owns.
  NSInputStream* CreateInputStream() {
    CFStreamClientContext context = {
        .version = 0,
        .info = this,
        .retain = nullptr,
        .release = nullptr,
        .copyDescription = nullptr
    };
    constexpr CFReadStreamCallBacksV0 callbacks = {
        .version = 0,
        .open = &Open,
        .openCompleted = &OpenCompleted,
        .read = &Read,
        .getBuffer = &GetBuffer,
        .canRead = &CanRead,
        .close = &Close,
        .copyProperty = &CopyProperty,
        .schedule = &Schedule,
        .unschedule = &Unschedule
    };
    CFReadStreamRef read_stream = CFReadStreamCreate(nullptr,
        reinterpret_cast<const CFReadStreamCallBacks*>(&callbacks), &context);
    return base::mac::CFToNSCast(read_stream);
  }

 private:
  static HTTPBodyStream* GetStream(void* info) {
    return static_cast<HTTPBodyStreamCFReadStream*>(info)->body_stream_;
  }

  static Boolean Open(CFReadStreamRef stream,
                      CFStreamError* error,
                      Boolean* open_complete,
                      void* info) {
    *open_complete = TRUE;
    return TRUE;
  }

  static Boolean OpenCompleted(CFReadStreamRef stream,
                               CFStreamError* error,
                               void* info) {
    return TRUE;
  }

  static CFIndex Read(CFReadStreamRef stream,
                      UInt8* buffer,
                      CFIndex buffer_length,
                      CFStreamError* error,
                      Boolean* at_eof,
                      void* info) {
    if (buffer_length == 0) {
      *at_eof = FALSE;
      return 0;
    }

    FileOperationResult bytes_read =
        GetStream(info)->GetBytesBuffer(buffer, buffer_length);
    if (bytes_read < 0) {
      error->error = -1;
      error->domain = kCFStreamErrorDomainCustom;
    } else {
      *at_eof = bytes_read == 0;
    }

    return bytes_read;
  }

  static const UInt8* GetBuffer(CFReadStreamRef stream,
                                CFIndex max_bytes_to_read,
                                CFIndex* num_bytes_read,
                                CFStreamError* error,
                                Boolean* at_eof,
                                void* info) {
    return nullptr;
  }

  static Boolean CanRead(CFReadStreamRef stream, void* info) {
    return TRUE;
  }

  static void Close(CFReadStreamRef stream, void* info) {}

  static CFTypeRef CopyProperty(CFReadStreamRef stream,
                                CFStringRef property_name,
                                void* info) {
    return nullptr;
  }

  static void Schedule(CFReadStreamRef stream,
                       CFRunLoopRef run_loop,
                       CFStringRef run_loop_mode,
                       void* info) {}

  static void Unschedule(CFReadStreamRef stream,
                         CFRunLoopRef run_loop,
                         CFStringRef run_loop_mode,
                         void* info) {}

  HTTPBodyStream* body_stream_;  // weak
};

class HTTPTransportMac final : public HTTPTransport {
 public:
  HTTPTransportMac();

  HTTPTransportMac(const HTTPTransportMac&) = delete;
  HTTPTransportMac& operator=(const HTTPTransportMac&) = delete;

  ~HTTPTransportMac() override;

  bool ExecuteSynchronously(std::string* response_body) override;
};

HTTPTransportMac::HTTPTransportMac() : HTTPTransport() {
}

HTTPTransportMac::~HTTPTransportMac() {
}

bool HTTPTransportMac::ExecuteSynchronously(std::string* response_body) {
  DCHECK(body_stream());

  @autoreleasepool {
    NSString* url_ns_string = base::SysUTF8ToNSString(url());
    NSURL* url = [NSURL URLWithString:url_ns_string];
    NSMutableURLRequest* request =
        [NSMutableURLRequest requestWithURL:url
                                cachePolicy:NSURLRequestUseProtocolCachePolicy
                            timeoutInterval:timeout()];
    [request setHTTPMethod:base::SysUTF8ToNSString(method())];

    // If left to its own devices, CFNetwork would build a user-agent string
    // based on keys in the main bundle’s Info.plist, giving ugly results if
    // there is no Info.plist. Provide a User-Agent string similar to the one
    // that CFNetwork would use, but with appropriate values in place of the
    // Info.plist-derived strings.
    [request setValue:UserAgentString() forHTTPHeaderField:@"User-Agent"];

    for (const auto& pair : headers()) {
      [request setValue:base::SysUTF8ToNSString(pair.second)
          forHTTPHeaderField:base::SysUTF8ToNSString(pair.first)];
    }

    HTTPBodyStreamCFReadStream body_stream_cf(body_stream());
    base::scoped_nsobject<NSInputStream> input_stream(
        body_stream_cf.CreateInputStream());
    [request setHTTPBodyStream:input_stream.get()];

    NSURLResponse* response = nil;
    NSError* error = nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    // Deprecated in OS X 10.11. The suggested replacement, NSURLSession, is
    // only available on 10.9 and later, and this needs to run on earlier
    // releases.
    NSData* body = [NSURLConnection sendSynchronousRequest:request
                                         returningResponse:&response
                                                     error:&error];
#pragma clang diagnostic pop

    if (error) {
      LOG(ERROR) << [[error localizedDescription] UTF8String] << " ("
                 << [[error domain] UTF8String] << " " << [error code] << ")";
      return false;
    }
    if (!response) {
      LOG(ERROR) << "no response";
      return false;
    }
    NSHTTPURLResponse* http_response =
        base::mac::ObjCCast<NSHTTPURLResponse>(response);
    if (!http_response) {
      LOG(ERROR) << "no http_response";
      return false;
    }
    NSInteger http_status = [http_response statusCode];
    if (http_status < 200 || http_status > 203) {
      LOG(ERROR) << base::StringPrintf("HTTP status %ld",
                                       implicit_cast<long>(http_status));
      return false;
    }

    if (response_body) {
      response_body->assign(static_cast<const char*>([body bytes]),
                            [body length]);
    }

    return true;
  }
}

}  // namespace

// static
std::unique_ptr<HTTPTransport> HTTPTransport::Create() {
  return std::unique_ptr<HTTPTransport>(new HTTPTransportMac());
}

}  // namespace crashpad
