# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

__all__ = ['Profile',
           'FirefoxProfile',
           'MetroFirefoxProfile',
           'ThunderbirdProfile']

import os
import time
import tempfile
import types
import uuid

from addons import AddonManager
import mozfile
from permissions import Permissions
from prefs import Preferences
from shutil import copytree
from webapps import WebappCollection


class Profile(object):
    """Handles all operations regarding profile.

    Creating new profiles, installing add-ons, setting preferences and
    handling cleanup.

    The files associated with the profile will be removed automatically after
    the object is garbage collected: ::

      profile = Profile()
      print profile.profile  # this is the path to the created profile
      del profile
      # the profile path has been removed from disk

    :meth:`cleanup` is called under the hood to remove the profile files. You
    can ensure this method is called (even in the case of exception) by using
    the profile as a context manager: ::

      with Profile() as profile:
          # do things with the profile
          pass
      # profile.cleanup() has been called here
    """

    def __init__(self, profile=None, addons=None, addon_manifests=None, apps=None,
                 preferences=None, locations=None, proxy=None, restore=True):
        """
        :param profile: Path to the profile
        :param addons: String of one or list of addons to install
        :param addon_manifests: Manifest for addons (see http://bit.ly/17jQ7i6)
        :param apps: Dictionary or class of webapps to install
        :param preferences: Dictionary or class of preferences
        :param locations: ServerLocations object
        :param proxy: Setup a proxy
        :param restore: Flag for removing all custom settings during cleanup
        """
        self._addons = addons
        self._addon_manifests = addon_manifests
        self._apps = apps
        self._locations = locations
        self._proxy = proxy

        # Prepare additional preferences
        if preferences:
            if isinstance(preferences, dict):
                # unordered
                preferences = preferences.items()

            # sanity check
            assert not [i for i in preferences if len(i) != 2]
        else:
            preferences = []
        self._preferences = preferences

        # Handle profile creation
        self.create_new = not profile
        if profile:
            # Ensure we have a full path to the profile
            self.profile = os.path.abspath(os.path.expanduser(profile))
        else:
            self.profile = tempfile.mkdtemp(suffix='.mozrunner')

        self.restore = restore

        # Initialize all class members
        self._internal_init()

    def _internal_init(self):
        """Internal: Initialize all class members to their default value"""

        if not os.path.exists(self.profile):
            os.makedirs(self.profile)

        # Preferences files written to
        self.written_prefs = set()

        # Our magic markers
        nonce = '%s %s' % (str(time.time()), uuid.uuid4())
        self.delimeters = ('#MozRunner Prefs Start %s' % nonce,
                           '#MozRunner Prefs End %s' % nonce)

        # If sub-classes want to set default preferences
        if hasattr(self.__class__, 'preferences'):
            self.set_preferences(self.__class__.preferences)
        # Set additional preferences
        self.set_preferences(self._preferences)

        self.permissions = Permissions(self.profile, self._locations)
        prefs_js, user_js = self.permissions.network_prefs(self._proxy)
        self.set_preferences(prefs_js, 'prefs.js')
        self.set_preferences(user_js)

        # handle add-on installation
        self.addon_manager = AddonManager(self.profile, restore=self.restore)
        self.addon_manager.install_addons(self._addons, self._addon_manifests)

        # handle webapps
        self.webapps = WebappCollection(profile=self.profile, apps=self._apps)
        self.webapps.update_manifests()

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.cleanup()

    def __del__(self):
        self.cleanup()

    ### cleanup

    def cleanup(self):
        """Cleanup operations for the profile."""

        if self.restore:
            # If copies of those class instances exist ensure we correctly
            # reset them all (see bug 934484)
            self.clean_preferences()
            if getattr(self, 'addon_manager', None) is not None:
                self.addon_manager.clean()
            if getattr(self, 'permissions', None) is not None:
                self.permissions.clean_db()
            if getattr(self, 'webapps', None) is not None:
                self.webapps.clean()

            # If it's a temporary profile we have to remove it
            if self.create_new:
                mozfile.remove(self.profile)

    def reset(self):
        """
        reset the profile to the beginning state
        """
        self.cleanup()

        self._internal_init()

    def clean_preferences(self):
        """Removed preferences added by mozrunner."""
        for filename in self.written_prefs:
            if not os.path.exists(os.path.join(self.profile, filename)):
                # file has been deleted
                break
            while True:
                if not self.pop_preferences(filename):
                    break

    @classmethod
    def clone(cls, path_from, path_to=None, **kwargs):
        """Instantiate a temporary profile via cloning
        - path: path of the basis to clone
        - kwargs: arguments to the profile constructor
        """
        if not path_to:
            tempdir = tempfile.mkdtemp() # need an unused temp dir name
            mozfile.remove(tempdir) # copytree requires that dest does not exist
            path_to = tempdir
        copytree(path_from, path_to)

        c = cls(path_to, **kwargs)
        c.create_new = True  # deletes a cloned profile when restore is True
        return c

    def exists(self):
        """returns whether the profile exists or not"""
        return os.path.exists(self.profile)

    ### methods for preferences

    def set_preferences(self, preferences, filename='user.js'):
        """Adds preferences dict to profile preferences"""

        # append to the file
        prefs_file = os.path.join(self.profile, filename)
        f = open(prefs_file, 'a')

        if preferences:

            # note what files we've touched
            self.written_prefs.add(filename)

            # opening delimeter
            f.write('\n%s\n' % self.delimeters[0])

            # write the preferences
            Preferences.write(f, preferences)

            # closing delimeter
            f.write('%s\n' % self.delimeters[1])

        f.close()

    def set_persistent_preferences(self, preferences):
        """
        Adds preferences dict to profile preferences and save them during a
        profile reset
        """

        # this is a dict sometimes, convert
        if isinstance(preferences, dict):
            preferences = preferences.items()

        # add new prefs to preserve them during reset
        for new_pref in preferences:
            # if dupe remove item from original list
            self._preferences = [
                pref for pref in self._preferences if not new_pref[0] == pref[0]]
            self._preferences.append(new_pref)

        self.set_preferences(preferences, filename='user.js')

    def pop_preferences(self, filename):
        """
        pop the last set of preferences added
        returns True if popped
        """

        path = os.path.join(self.profile, filename)
        with file(path) as f:
            lines = f.read().splitlines()
        def last_index(_list, value):
            """
            returns the last index of an item;
            this should actually be part of python code but it isn't
            """
            for index in reversed(range(len(_list))):
                if _list[index] == value:
                    return index
        s = last_index(lines, self.delimeters[0])
        e = last_index(lines, self.delimeters[1])

        # ensure both markers are found
        if s is None:
            assert e is None, '%s found without %s' % (self.delimeters[1], self.delimeters[0])
            return False # no preferences found
        elif e is None:
            assert s is None, '%s found without %s' % (self.delimeters[0], self.delimeters[1])

        # ensure the markers are in the proper order
        assert e > s, '%s found at %s, while %s found at %s' % (self.delimeters[1], e, self.delimeters[0], s)

        # write the prefs
        cleaned_prefs = '\n'.join(lines[:s] + lines[e+1:])
        with file(path, 'w') as f:
            f.write(cleaned_prefs)
        return True

    ### methods for introspection

    def summary(self, return_parts=False):
        """
        returns string summarizing profile information.
        if return_parts is true, return the (Part_name, value) list
        of tuples instead of the assembled string
        """

        parts = [('Path', self.profile)] # profile path

        # directory tree
        parts.append(('Files', '\n%s' % mozfile.tree(self.profile)))

        # preferences
        for prefs_file in ('user.js', 'prefs.js'):
            path = os.path.join(self.profile, prefs_file)
            if os.path.exists(path):

                # prefs that get their own section
                # This is currently only 'network.proxy.autoconfig_url'
                # but could be expanded to include others
                section_prefs = ['network.proxy.autoconfig_url']
                line_length = 80
                line_length_buffer = 10 # buffer for 80 character display: length = 80 - len(key) - len(': ') - line_length_buffer
                line_length_buffer += len(': ')
                def format_value(key, value):
                    if key not in section_prefs:
                        return value
                    max_length = line_length - len(key) - line_length_buffer
                    if len(value) > max_length:
                        value = '%s...' % value[:max_length]
                    return value

                prefs = Preferences.read_prefs(path)
                if prefs:
                    prefs = dict(prefs)
                    parts.append((prefs_file,
                    '\n%s' %('\n'.join(['%s: %s' % (key, format_value(key, prefs[key]))
                                        for key in sorted(prefs.keys())
                                        ]))))

                    # Currently hardcorded to 'network.proxy.autoconfig_url'
                    # but could be generalized, possibly with a generalized (simple)
                    # JS-parser
                    network_proxy_autoconfig = prefs.get('network.proxy.autoconfig_url')
                    if network_proxy_autoconfig and network_proxy_autoconfig.strip():
                        network_proxy_autoconfig = network_proxy_autoconfig.strip()
                        lines = network_proxy_autoconfig.replace(';', ';\n').splitlines()
                        lines = [line.strip() for line in lines]
                        origins_string = 'var origins = ['
                        origins_end = '];'
                        if origins_string in lines[0]:
                            start = lines[0].find(origins_string)
                            end = lines[0].find(origins_end, start);
                            splitline = [lines[0][:start],
                                         lines[0][start:start+len(origins_string)-1],
                                         ]
                            splitline.extend(lines[0][start+len(origins_string):end].replace(',', ',\n').splitlines())
                            splitline.append(lines[0][end:])
                            lines[0:1] = [i.strip() for i in splitline]
                        parts.append(('Network Proxy Autoconfig, %s' % (prefs_file),
                                      '\n%s' % '\n'.join(lines)))

        if return_parts:
            return parts

        retval = '%s\n' % ('\n\n'.join(['[%s]: %s' % (key, value)
                                        for key, value in parts]))
        return retval

    __str__ = summary


class FirefoxProfile(Profile):
    """Specialized Profile subclass for Firefox"""

    preferences = {# Don't automatically update the application
                   'app.update.enabled' : False,
                   # Don't restore the last open set of tabs if the browser has crashed
                   'browser.sessionstore.resume_from_crash': False,
                   # Don't check for the default web browser during startup
                   'browser.shell.checkDefaultBrowser' : False,
                   # Don't warn on exit when multiple tabs are open
                   'browser.tabs.warnOnClose' : False,
                   # Don't warn when exiting the browser
                   'browser.warnOnQuit': False,
                   # Don't send Firefox health reports to the production server
                   'datareporting.healthreport.documentServerURI' : 'http://%(server)s/healthreport/',
                   # Only install add-ons from the profile and the application scope
                   # Also ensure that those are not getting disabled.
                   # see: https://developer.mozilla.org/en/Installing_extensions
                   'extensions.enabledScopes' : 5,
                   'extensions.autoDisableScopes' : 10,
                   # Don't send the list of installed addons to AMO
                   'extensions.getAddons.cache.enabled' : False,
                   # Don't install distribution add-ons from the app folder
                   'extensions.installDistroAddons' : False,
                   # Dont' run the add-on compatibility check during start-up
                   'extensions.showMismatchUI' : False,
                   # Don't automatically update add-ons
                   'extensions.update.enabled'    : False,
                   # Don't open a dialog to show available add-on updates
                   'extensions.update.notifyUser' : False,
                   # Enable test mode to run multiple tests in parallel
                   'focusmanager.testmode' : True,
                   # Enable test mode to not raise an OS level dialog for location sharing
                   'geo.provider.testing' : True,
                   # Suppress delay for main action in popup notifications
                   'security.notification_enable_delay' : 0,
                   # Suppress automatic safe mode after crashes
                   'toolkit.startup.max_resumed_crashes' : -1,
                   # Don't report telemetry information
                   'toolkit.telemetry.enabled' : False,
                   # Don't send Telemetry reports to the production server. This is
                   # needed as Telemetry sends pings also if FHR upload is enabled.
                   'toolkit.telemetry.server' : 'http://%(server)s/telemetry-dummy/',
                   # Our current tests expect the unified Telemetry feature to be opt-out,
                   # which is not true while we hold back shipping it.
                   'toolkit.telemetry.unifiedIsOptIn': True,
                   }

class MetroFirefoxProfile(Profile):
    """Specialized Profile subclass for Firefox Metro"""

    preferences = {# Don't automatically update the application for desktop and metro build
                   'app.update.enabled' : False,
                   'app.update.metro.enabled' : False,
                   # Dismiss first run content overlay
                   'browser.firstrun-content.dismissed' : True,
                   # Don't restore the last open set of tabs if the browser has crashed
                   'browser.sessionstore.resume_from_crash': False,
                   # Don't check for the default web browser during startup
                   'browser.shell.checkDefaultBrowser' : False,
                   # Don't send Firefox health reports to the production server
                   'datareporting.healthreport.documentServerURI' : 'http://%(server)s/healthreport/',
                   # Enable extensions
                   'extensions.defaultProviders.enabled' : True,
                   # Only install add-ons from the profile and the application scope
                   # Also ensure that those are not getting disabled.
                   # see: https://developer.mozilla.org/en/Installing_extensions
                   'extensions.enabledScopes' : 5,
                   'extensions.autoDisableScopes' : 10,
                   # Don't send the list of installed addons to AMO
                   'extensions.getAddons.cache.enabled' : False,
                   # Don't install distribution add-ons from the app folder
                   'extensions.installDistroAddons' : False,
                   # Dont' run the add-on compatibility check during start-up
                   'extensions.showMismatchUI' : False,
                   # Disable strict compatibility checks to allow add-ons enabled by default
                   'extensions.strictCompatibility' : False,
                   # Don't automatically update add-ons
                   'extensions.update.enabled'    : False,
                   # Don't open a dialog to show available add-on updates
                   'extensions.update.notifyUser' : False,
                   # Enable test mode to run multiple tests in parallel
                   'focusmanager.testmode' : True,
                   # Suppress delay for main action in popup notifications
                   'security.notification_enable_delay' : 0,
                   # Suppress automatic safe mode after crashes
                   'toolkit.startup.max_resumed_crashes' : -1,
                   # Don't report telemetry information
                   'toolkit.telemetry.enabled' : False,
                   # Don't send Telemetry reports to the production server. This is
                   # needed as Telemetry sends pings also if FHR upload is enabled.
                   'toolkit.telemetry.server' : 'http://%(server)s/telemetry-dummy/',
                   }

class ThunderbirdProfile(Profile):
    """Specialized Profile subclass for Thunderbird"""

    preferences = {'extensions.update.enabled'    : False,
                   'extensions.update.notifyUser' : False,
                   'browser.shell.checkDefaultBrowser' : False,
                   'browser.tabs.warnOnClose' : False,
                   'browser.warnOnQuit': False,
                   'browser.sessionstore.resume_from_crash': False,
                   # prevents the 'new e-mail address' wizard on new profile
                   'mail.provider.enabled': False,
                   }
