// 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.

#include "rlz/mac/lib/rlz_value_store_mac.h"

#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "rlz/lib/assert.h"
#include "rlz/lib/lib_values.h"
#include "rlz/lib/recursive_cross_process_lock_posix.h"
#include "rlz/lib/rlz_lib.h"

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

using base::mac::ObjCCast;

namespace rlz_lib {

// These are written to disk and should not be changed.
NSString* const kPingTimeKey = @"pingTime";
NSString* const kAccessPointKey = @"accessPoints";
NSString* const kProductEventKey = @"productEvents";
NSString* const kStatefulEventKey = @"statefulEvents";

namespace {

NSString* GetNSProductName(Product product) {
  return base::SysUTF8ToNSString(GetProductName(product));
}

NSString* GetNSAccessPointName(AccessPoint p) {
  return base::SysUTF8ToNSString(GetAccessPointName(p));
}

// Retrieves a subdictionary in |p| for key |k|, creating it if necessary.
// If the dictionary contains an object for |k| that is not a mutable
// dictionary, that object is replaced with an empty mutable dictinary.
NSMutableDictionary* GetOrCreateDict(
    NSMutableDictionary* p, NSString* k) {
  NSMutableDictionary* d = ObjCCast<NSMutableDictionary>([p objectForKey:k]);
  if (!d) {
    d = [NSMutableDictionary dictionaryWithCapacity:0];
    [p setObject:d forKey:k];
  }
  return d;
}

}  // namespace

RlzValueStoreMac::RlzValueStoreMac(NSMutableDictionary* dict,
                                   NSString* plist_path)
  : dict_([dict retain]), plist_path_([plist_path retain]) {
}

RlzValueStoreMac::~RlzValueStoreMac() {
}

bool RlzValueStoreMac::HasAccess(AccessType type) {
  NSFileManager* manager = [NSFileManager defaultManager];
  switch (type) {
    case kReadAccess:  return [manager isReadableFileAtPath:plist_path_];
    case kWriteAccess: return [manager isWritableFileAtPath:plist_path_];
  }
}

bool RlzValueStoreMac::WritePingTime(Product product, int64 time) {
  NSNumber* n = [NSNumber numberWithLongLong:time];
  [ProductDict(product) setObject:n forKey:kPingTimeKey];
  return true;
}

bool RlzValueStoreMac::ReadPingTime(Product product, int64* time) {
  if (NSNumber* n =
      ObjCCast<NSNumber>([ProductDict(product) objectForKey:kPingTimeKey])) {
    *time = [n longLongValue];
    return true;
  }
  return false;
}

bool RlzValueStoreMac::ClearPingTime(Product product) {
  [ProductDict(product) removeObjectForKey:kPingTimeKey];
  return true;
}


bool RlzValueStoreMac::WriteAccessPointRlz(AccessPoint access_point,
                                           const char* new_rlz) {
  NSMutableDictionary* d = GetOrCreateDict(WorkingDict(), kAccessPointKey);
  [d setObject:base::SysUTF8ToNSString(new_rlz)
      forKey:GetNSAccessPointName(access_point)];
  return true;
}

bool RlzValueStoreMac::ReadAccessPointRlz(AccessPoint access_point,
                                          char* rlz,
                                          size_t rlz_size) {
  // Reading a non-existent access point counts as success.
  if (NSDictionary* d = ObjCCast<NSDictionary>(
        [WorkingDict() objectForKey:kAccessPointKey])) {
    NSString* val = ObjCCast<NSString>(
        [d objectForKey:GetNSAccessPointName(access_point)]);
    if (!val) {
      if (rlz_size > 0)
        rlz[0] = '\0';
      return true;
    }

    std::string s = base::SysNSStringToUTF8(val);
    if (s.size() >= rlz_size) {
      rlz[0] = 0;
      ASSERT_STRING("GetAccessPointRlz: Insufficient buffer size");
      return false;
    }
    strncpy(rlz, s.c_str(), rlz_size);
    return true;
  }
  if (rlz_size > 0)
    rlz[0] = '\0';
  return true;
}

bool RlzValueStoreMac::ClearAccessPointRlz(AccessPoint access_point) {
  if (NSMutableDictionary* d = ObjCCast<NSMutableDictionary>(
      [WorkingDict() objectForKey:kAccessPointKey])) {
    [d removeObjectForKey:GetNSAccessPointName(access_point)];
  }
  return true;
}


bool RlzValueStoreMac::AddProductEvent(Product product,
                                       const char* event_rlz) {
  [GetOrCreateDict(ProductDict(product), kProductEventKey)
      setObject:[NSNumber numberWithBool:YES]
      forKey:base::SysUTF8ToNSString(event_rlz)];
  return true;
}

bool RlzValueStoreMac::ReadProductEvents(Product product,
                                         std::vector<std::string>* events) {
  if (NSDictionary* d = ObjCCast<NSDictionary>(
      [ProductDict(product) objectForKey:kProductEventKey])) {
    for (NSString* s in d)
      events->push_back(base::SysNSStringToUTF8(s));
    return true;
  }
  return true;
}

bool RlzValueStoreMac::ClearProductEvent(Product product,
                                         const char* event_rlz) {
  if (NSMutableDictionary* d = ObjCCast<NSMutableDictionary>(
      [ProductDict(product) objectForKey:kProductEventKey])) {
    [d removeObjectForKey:base::SysUTF8ToNSString(event_rlz)];
    return true;
  }
  return false;
}

bool RlzValueStoreMac::ClearAllProductEvents(Product product) {
  [ProductDict(product) removeObjectForKey:kProductEventKey];
  return true;
}


bool RlzValueStoreMac::AddStatefulEvent(Product product,
                                        const char* event_rlz) {
  [GetOrCreateDict(ProductDict(product), kStatefulEventKey)
      setObject:[NSNumber numberWithBool:YES]
      forKey:base::SysUTF8ToNSString(event_rlz)];
  return true;
}

bool RlzValueStoreMac::IsStatefulEvent(Product product,
                                       const char* event_rlz) {
  if (NSDictionary* d = ObjCCast<NSDictionary>(
        [ProductDict(product) objectForKey:kStatefulEventKey])) {
    return [d objectForKey:base::SysUTF8ToNSString(event_rlz)] != nil;
  }
  return false;
}

bool RlzValueStoreMac::ClearAllStatefulEvents(Product product) {
  [ProductDict(product) removeObjectForKey:kStatefulEventKey];
  return true;
}


void RlzValueStoreMac::CollectGarbage() {
  NOTIMPLEMENTED();
}

NSDictionary* RlzValueStoreMac::dictionary() {
  return dict_.get();
}

NSMutableDictionary* RlzValueStoreMac::WorkingDict() {
  std::string brand(SupplementaryBranding::GetBrand());
  if (brand.empty())
    return dict_;

  NSString* brand_ns =
      [@"brand_" stringByAppendingString:base::SysUTF8ToNSString(brand)];

  return GetOrCreateDict(dict_.get(), brand_ns);
}

NSMutableDictionary* RlzValueStoreMac::ProductDict(Product p) {
  return GetOrCreateDict(WorkingDict(), GetNSProductName(p));
}


namespace {

RecursiveCrossProcessLock g_recursive_lock =
    RECURSIVE_CROSS_PROCESS_LOCK_INITIALIZER;

// This is set during test execution, to write RLZ files into a temporary
// directory instead of the user's Application Support folder.
NSString* g_test_folder;

// RlzValueStoreMac keeps its data in memory and only writes it to disk when
// ScopedRlzValueStoreLock goes out of scope. Hence, if several
// ScopedRlzValueStoreLocks are nested, they all need to use the same store
// object.

// This counts the nesting depth.
int g_lock_depth = 0;

// This is the store object that might be shared. Only set if g_lock_depth > 0.
RlzValueStoreMac* g_store_object = NULL;


NSString* CreateRlzDirectory() {
  NSFileManager* manager = [NSFileManager defaultManager];
  NSArray* paths = NSSearchPathForDirectoriesInDomains(
      NSApplicationSupportDirectory, NSUserDomainMask, /*expandTilde=*/YES);
  NSString* folder = nil;
  if ([paths count] > 0)
    folder = ObjCCast<NSString>([paths objectAtIndex:0]);
  if (!folder)
    folder = [@"~/Library/Application Support" stringByStandardizingPath];
  folder = [folder stringByAppendingPathComponent:@"Google/RLZ"];

  if (g_test_folder)
    folder = [g_test_folder stringByAppendingPathComponent:folder];

  [manager createDirectoryAtPath:folder
     withIntermediateDirectories:YES
                      attributes:nil
                           error:nil];
  return folder;
}

// Returns the path of the rlz plist store, also creates the parent directory
// path if it doesn't exist.
NSString* RlzPlistFilename() {
  NSString* const kRlzFile = @"RlzStore.plist";
  return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzFile];
}

// Returns the path of the rlz lock file, also creates the parent directory
// path if it doesn't exist.
NSString* RlzLockFilename() {
  NSString* const kRlzLockfile = @"flockfile";
  return [CreateRlzDirectory() stringByAppendingPathComponent:kRlzLockfile];
}

}  // namespace

ScopedRlzValueStoreLock::ScopedRlzValueStoreLock() {
  bool got_distributed_lock = g_recursive_lock.TryGetCrossProcessLock(
      base::FilePath([RlzLockFilename() fileSystemRepresentation]));
  // At this point, we hold the in-process lock, no matter the value of
  // |got_distributed_lock|.

  ++g_lock_depth;

  if (!got_distributed_lock) {
    // Give up. |store_| isn't set, which signals to callers that acquiring
    // the lock failed. |g_recursive_lock| will be released by the
    // destructor.
    CHECK(!g_store_object);
    return;
  }

  if (g_lock_depth > 1) {
    // Reuse the already existing store object. Note that it can be NULL when
    // lock acquisition succeeded but the rlz data file couldn't be read.
    store_.reset(g_store_object);
    return;
  }

  CHECK(!g_store_object);

  NSString* plist = RlzPlistFilename();

  // Create an empty file if none exists yet.
  NSFileManager* manager = [NSFileManager defaultManager];
  if (![manager fileExistsAtPath:plist isDirectory:NULL])
    [[NSDictionary dictionary] writeToFile:plist atomically:YES];

  NSMutableDictionary* dict =
      [NSMutableDictionary dictionaryWithContentsOfFile:plist];
  VERIFY(dict);

  if (dict) {
    store_.reset(new RlzValueStoreMac(dict, plist));
    g_store_object = (RlzValueStoreMac*)store_.get();
  }
}

ScopedRlzValueStoreLock::~ScopedRlzValueStoreLock() {
  --g_lock_depth;
  CHECK(g_lock_depth >= 0);

  if (g_lock_depth > 0) {
    // Other locks are still using store_, don't free it yet.
    ignore_result(store_.release());
    return;
  }

  if (store_.get()) {
    g_store_object = NULL;

    NSDictionary* dict =
        static_cast<RlzValueStoreMac*>(store_.get())->dictionary();
    VERIFY([dict writeToFile:RlzPlistFilename() atomically:YES]);
  }

  // Check that "store_ set" => "file_lock acquired". The converse isn't true,
  // for example if the rlz data file can't be read.
  if (store_.get())
    CHECK(g_recursive_lock.file_lock_ != -1);
  if (g_recursive_lock.file_lock_ == -1)
    CHECK(!store_.get());

  g_recursive_lock.ReleaseLock();
}

RlzValueStore* ScopedRlzValueStoreLock::GetStore() {
  return store_.get();
}

namespace testing {

void SetRlzStoreDirectory(const base::FilePath& directory) {
  base::mac::ScopedNSAutoreleasePool pool;

  [g_test_folder release];
  if (directory.empty()) {
    g_test_folder = nil;
  } else {
    // Not Unsafe on OS X.
    g_test_folder =
      [[NSString alloc] initWithUTF8String:directory.AsUTF8Unsafe().c_str()];
  }
}

std::string RlzStoreFilenameStr() {
  @autoreleasepool {
    return std::string([RlzPlistFilename() fileSystemRepresentation]);
  }
}

}  // namespace testing

}  // namespace rlz_lib
