// Copyright 2010-2015, Google 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:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
// OWNER OR 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 "ActivatePane.h"

#import <Carbon/Carbon.h>
#import <Foundation/Foundation.h>

#ifdef GOOGLE_JAPANESE_INPUT_BUILD
static const unsigned char kInstalledLocation[] =
    "/Library/Input Methods/GoogleJapaneseInput.app";
static NSString *kLaunchdPlistFiles[] = {
  @"/Library/LaunchAgents/com.google.inputmethod.Japanese.Converter.plist",
  @"/Library/LaunchAgents/com.google.inputmethod.Japanese.Renderer.plist",
  nil};
static NSString *const kSourceID = @"com.google.inputmethod.Japanese";
#else  // GOOGLE_JAPANESE_INPUT_BUILD
static const unsigned char kInstalledLocation[] =
    "/Library/Input Methods/Mozc.app";
static NSString *kLaunchdPlistFiles[] = {
  @"/Library/LaunchAgents/org.mozc.inputmethod.Japanese.Converter.plist",
  @"/Library/LaunchAgents/org.mozc.inputmethod.Japanese.Renderer.plist",
  nil};
static NSString *const kSourceID = @"org.mozc.inputmethod.Japanese";
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

// Load the installed Google Japanese Input to the system.
static void RegisterGoogleJapaneseInput() {
  CFURLRef installedLocationURL = CFURLCreateFromFileSystemRepresentation(
      NULL,  kInstalledLocation, strlen((const char *)kInstalledLocation), NO);
  if (installedLocationURL) {
    TISRegisterInputSource(installedLocationURL);
  }
}

// Put modes of Google Japanese Input at the list of pull-down menu
// for IMEs, and make it as the default IME.
static void ActivateGoogleJapaneseInput() {
  CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
  for (int i = 0; i < CFArrayGetCount(sourceList); ++i) {
    TISInputSourceRef inputSource = (TISInputSourceRef)(CFArrayGetValueAtIndex(
        sourceList, i));
    NSString *sourceID = (NSString *)(TISGetInputSourceProperty(
        inputSource, kTISPropertyInputSourceID));
    if ([sourceID isEqualToString:kSourceID]) {
      TISEnableInputSource(inputSource);
      TISSelectInputSource(inputSource);
      break;
    }
  }
}

// Load the launchd preferences
static void LoadLaunchdPlistFiles() {
  int i = 0;
  for (; kLaunchdPlistFiles[i] != nil; ++i) {
    NSArray *arguments =
        [NSArray arrayWithObjects:@"load", @"-S", @"Aqua",
                 kLaunchdPlistFiles[i], nil];
    NSTask *task = [NSTask launchedTaskWithLaunchPath:@"/bin/launchctl"
                                            arguments:arguments];
    [task waitUntilExit];
  }
}

// Check if Google Japanese Input is already active on the user
// machine (e.g. the user already installed Google Japanese Input).
// Called at the initialization of this module.
static BOOL IsAlreadyActive() {
  BOOL isActive = NO;
  CFArrayRef sourceList = TISCreateInputSourceList(NULL, true);
  for (int i = 0; i < CFArrayGetCount(sourceList); ++i) {
    TISInputSourceRef inputSource = (TISInputSourceRef)(CFArrayGetValueAtIndex(
        sourceList, i));
    NSString *sourceID = (NSString *)(TISGetInputSourceProperty(
        inputSource, kTISPropertyInputSourceID));
    if ([sourceID isEqualToString:kSourceID]) {
      CFBooleanRef isEnabled = (CFBooleanRef)(TISGetInputSourceProperty(
          inputSource, kTISPropertyInputSourceIsEnabled));
      CFBooleanRef isSelected = (CFBooleanRef)(TISGetInputSourceProperty(
          inputSource, kTISPropertyInputSourceIsEnabled));
      if (CFBooleanGetValue(isEnabled) || CFBooleanGetValue(isSelected)) {
        isActive = YES;
        break;
      }
    }
  }
  return isActive;
}

// Check if the usagestats.db file already exists.  Called at the
// initialization of this module.
static BOOL HasUsageStatsDB() {
  // If channel is dev, we don't want to show the "turn-on usage
  // stats" button, so the situation is same as that there are already
  // usage stats config file.
#ifndef GOOGLE_JAPANESE_INPUT_BUILD
  return NO;
#elif defined(CHANNEL_DEV)
  return YES;
#endif  // CHANNEL_DEV
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(
      NSLibraryDirectory, NSUserDomainMask, YES);
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *libraryPath = nil;
  NSString *usageStatsDBPath = nil;
  BOOL exists = NO;
  if (libraryPaths == nil || [libraryPaths count] == 0) {
    [pool drain];
    return NO;
  }
  libraryPath = [libraryPaths objectAtIndex:0];
  usageStatsDBPath =
      [[[[libraryPath stringByAppendingPathComponent:@"Application Support"]
          stringByAppendingPathComponent:@"Google"]
        stringByAppendingPathComponent:@"JapaneseInput"]
        stringByAppendingPathComponent:@".usagestats.db"];
  exists = [fileManager fileExistsAtPath:usageStatsDBPath];
  [pool drain];
  return exists;
}

// Put the usagestats file of sending report onto the user's config
// directory.  This function should be called only if the user checks
// the |_putUsageStatsDB| button.
static BOOL StoreDefaultConfigWithSendingUsageStats() {
#ifndef GOOGLE_JAPANESE_INPUT_BUILD
  return NO;
#endif  // !GOOGLE_JAPANESE_INPUT_BUILD
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains(
      NSLibraryDirectory, NSUserDomainMask, YES);
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *libraryPath = nil;
  NSString *googlePath = nil;
  NSString *japaneseInputPath = nil;
  NSString *usageStatsDBPath = nil;
  if (libraryPaths == nil || [libraryPaths count] == 0) {
    [pool drain];
    return NO;
  }

  libraryPath = [libraryPaths objectAtIndex:0];
  googlePath =
      [[libraryPath stringByAppendingPathComponent:@"Application Support"]
        stringByAppendingPathComponent:@"Google"];
  if (![fileManager fileExistsAtPath:googlePath]) {
    NSDictionary *defaultAttributes =
        [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0755]
                                    forKey:NSFilePosixPermissions];
    if (![fileManager createDirectoryAtPath:googlePath
                withIntermediateDirectories:YES
                                 attributes:defaultAttributes
                                      error:NULL]) {
      [pool drain];
      return NO;
    }
  }

  japaneseInputPath =
      [googlePath stringByAppendingPathComponent:@"JapaneseInput"];
  if (![fileManager fileExistsAtPath:japaneseInputPath]) {
    NSDictionary *japaneseInputAttributes =
        [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0700]
                                    forKey:NSFilePosixPermissions];
    if (![fileManager createDirectoryAtPath:japaneseInputPath
                withIntermediateDirectories:YES
                                 attributes:japaneseInputAttributes
                                      error:NULL]) {
      [pool drain];
      return NO;
    }
  }

  usageStatsDBPath =
      [japaneseInputPath stringByAppendingPathComponent:@".usagestats.db"];
  if (![fileManager fileExistsAtPath:usageStatsDBPath]) {
    // The value of usage stats is a 32-bit int and 1 means "sending
    // the usage stats to Google".
    const int sending = 1;
    NSDictionary *usageStatsDBAttributes =
        [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0400]
                                    forKey:NSFilePosixPermissions];
    if ([fileManager createFileAtPath:usageStatsDBPath
                             contents:[NSData dataWithBytes:&sending
                                                     length:4]
                           attributes:usageStatsDBAttributes]) {
      [pool drain];
      return YES;
    }
  }

  [pool drain];
  return NO;
}

@interface ActivatePane ()
// Returns localized string for the key in the bundle.  Returns nil if
// not found.  This is a wrapper of [NSBundle localizedStringForKey:]
// which returns the key if not found.
- (NSString *)localizedStringForKey:(NSString *)key;
@end

@implementation ActivatePane
- (id)initWithSection:(id)parent {
  self = [super initWithSection:parent];
  _alreadyActivated = NO;
  _isUpgrade = NO;
  _hasUsageStatsDB = NO;
  return self;
}

// This method is called once when this module is loaded.
- (void)awakeFromNib {
  _isUpgrade = IsAlreadyActive();
  _hasUsageStatsDB = _isUpgrade || HasUsageStatsDB();
  if (_isUpgrade) {
    _alreadyActivated = YES;
  }
}

- (NSString *)title {
  NSString *titleString = [self localizedStringForKey:@"Title"];
  if (titleString) {
    return titleString;
  }
  return @"Automatic Activation";
}

// This method is called when the pane is visible.
- (void)willEnterPane:(InstallerSectionDirection)dir {
  // Main messages
  NSString *mainMessage = [self localizedStringForKey:@"mainMessage"];
  if (mainMessage) {
    [_mainMessage setStringValue:mainMessage];
  }

  // Upgrade Message. Blank if it's not upgrade.
  if (_isUpgrade) {
    NSString *upgradeMessage = [self localizedStringForKey:@"upgradeMessage"];
    if (upgradeMessage) {
      [_upgradeMessage setStringValue:upgradeMessage];
    }
  } else {
    [_upgradeMessage setStringValue:@""];
  }

  // Button label for "activate"
  NSString *activateLabel = [self localizedStringForKey:@"activateLabel"];
  if (activateLabel) {
    [_activateCell setTitle:activateLabel];
  }

  // Button label for "do not activate"
  NSString *doNotActivateLabel =
      [self localizedStringForKey:@"doNotActivateLabel"];
  if (doNotActivateLabel) {
    [_doNotActivateCell setTitle:doNotActivateLabel];
  }

  // usage stats message
#ifndef GOOGLE_JAPANESE_INPUT_BUILD
  [_putUsageStatsDB removeFromSuperview];
  [_putUsageStatsDBMessage removeFromSuperview];
#else  // GOOGLE_JAPANESE_INPUT_BUILD
  if (!_hasUsageStatsDB) {
    NSString *usageStatsMessage =
        [self localizedStringForKey:@"usageStatsMessage"];
    if (usageStatsMessage) {
      [_putUsageStatsDBMessage setStringValue:usageStatsMessage];
    }
  } else {
    [_putUsageStatsDB removeFromSuperview];
    [_putUsageStatsDBMessage removeFromSuperview];
  }
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

  if (_alreadyActivated) {
    [_mainMessage setEnabled:NO];
    [_activateCell setEnabled:NO];
    [_doNotActivateCell setEnabled:NO];
  }
}

// This method is called when the user leave the pane.
- (void)willExitPane:(InstallerSectionDirection)dir {
  if (dir == InstallerDirectionForward) {
    LoadLaunchdPlistFiles();
  }

  if (!_alreadyActivated &&
      dir == InstallerDirectionForward) {
    // Make the package visible from i18n system preference
    RegisterGoogleJapaneseInput();
    if ([_activateCell state] == NSOnState &&
        [_doNotActivateCell state] == NSOffState) {
      // means clicks "next page" when "activate" menu is on
      ActivateGoogleJapaneseInput();
      _alreadyActivated = YES;
    }
#ifdef GOOGLE_JAPANESE_INPUT_BUILD
    if (!_hasUsageStatsDB && [_putUsageStatsDB state] == NSOnState) {
      StoreDefaultConfigWithSendingUsageStats();
    }
#endif  // GOOGLE_JAPANESE_INPUT_BUILD
  }
}


- (NSString *)localizedStringForKey:(NSString *)key {
  NSBundle *bundle = [NSBundle bundleForClass:[self class]];
  if (!bundle) {
    return nil;
  }

  NSString *value = [bundle localizedStringForKey:key value:nil table:nil];
  // value is same as "key" if failed.
  if ([value isEqualToString:key]) {
    return nil;
  }
  return value;
}
@end
