import { Preferences } from "./lib/Preferences.js";
import { ProxyManager } from "./lib/ProxyManager.js";
import { ServerAPI } from "./lib/ServerAPI.js";
import { UserAgentList } from "./lib/UserAgentList.js";
	  
var Emit = function(options) {
  // decorator: compatibility with Firefox/Chrome
  chrome.runtime.sendMessage({
    message: options.message,
    content: options.content
  });
}

var Listen = function(options) {
  // decorator: compatibility with Firefox/Chrome
  chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (options.message == request.message)
      options.callback(request.content);
    sendResponse({message: true}); // was added since return true was not enough
    return true;
  });
}

var popupData = null;

var ShowHowToPopup = function(screenWidth, screenHeight) {
  var width = 816;
  var height = 624;

  var left = (screenWidth/2)-(width/2);
  var top = (screenHeight/2)-(height/2);
  chrome.tabs.create({
      url: chrome.runtime.getURL('/data/slider/slider.html'),
      active: false
  }, function(tab) {
      chrome.windows.create({
          tabId: tab.id,
          type: 'popup',
          focused: true,
          width: width,
          height: height,
          left: left,
          top: top
      });
  });
}

function WebRTC(enableWebRTC) {
  //var policy = enableWebRTC ? chrome.privacy.IPHandlingPolicy.DEFAULT : chrome.privacy.IPHandlingPolicy.DISABLE_NON_PROXIED_UDP;
  //try {chrome.privacy.network.webRTCIPHandlingPolicy.set({value: policy})} catch(err) {}
}

Listen({
  message: 'ConsoleLog',
  callback: function(message) {
    console.log((new Date()).getTime());
    console.log(message);
  }
})

Listen({
  message: 'InitializeBackground',
  callback: function(message) {
    Emit({
      message: 'InitializeContentScript',
      content: popupData
    })
  }
})

Listen({
  message: 'SavePopupBackground',
  callback: function(message) {
    popupData = message;
  }
})

Listen({
  message: 'SaveFavoriteBackground',
  callback: function(message) {
    Preferences.favoriteProxy = message.favoriteProxy;
    Preferences.SavePreferences();
  }
})

Listen({
  message: 'LoadPreferencesBackground',
  callback: function(message) {
    Preferences.LoadPreferences(function() {
      Preferences.LoadExtensionPreferences(function() {
        if ((new Date().getTime()) > Preferences.extensionPreferences.tutorial) {
          Preferences.extensionPreferences.tutorial = (new Date().getTime()) + 30*24*60*60*1000; // 30 days
          Preferences.SaveExtensionPreferences();
          Emit({
            message: 'HidePopupContentScript',
            content: {}
          });
          ShowHowToPopup(message.width, message.height);
        }
      })
      if (Preferences.profile.email && Preferences.profile.pass) {
        Emit({
          message: 'AutoLoginContentScript',
          content: {
            'email': Preferences.profile.email,
            'pass': Preferences.profile.pass
          }
        });
      }
      // TODO: if all three cache was not expired then show main automatically
      // TODO: catch any JS error and delete profile (global reset)
      // TODO: hit on 'enter' key must submit form
    })
  }
})

Listen({
  message: 'OpenLoginUrlBackground',
  callback: function(message) {
    function AuthUser(action, email, pass) {
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', action);
      var params = {amember_login: email, amember_pass: pass, amember_redirect_url: '/signup'};
      for(var key in params) {
        var field = document.createElement('input');
        field.setAttribute('type', 'hidden');
        field.setAttribute('name', key);
        field.setAttribute('value', params[key]);
        form.appendChild(field);
      }
      document.body.appendChild(form);
      form.submit();
    };
    
    chrome.tabs.create({url: message.action}, function(newTab) {
      // wait for the new tab to be fully loaded
      chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
        if (tabId === newTab.id && changeInfo.status === 'complete') {
          chrome.tabs.onUpdated.removeListener(listener);
          
          chrome.scripting.executeScript({
            target: {tabId: tabId},
            function: AuthUser,
            args: [message.action, message.user, message.pass]
          });
        }
      });
    });
  }
})

Listen({
  message: 'AbortRequestBackground',
  callback: function (message) {
    ServerAPI.AbortRequst();
  }
})

Listen({
  message: 'AuthenticateBackground',
  callback: function (message) {
    var GeoInformatoinSuccess = function() {
      var userGeoInfo = Preferences.userGeoInfo;
      Emit({
        message: 'GeoInformatoinContentScript',
        content: {'location': (userGeoInfo.city) ? userGeoInfo.country+', '+userGeoInfo.city : userGeoInfo.country}
      });
      var profile = Preferences.profile;
      Emit({
        message: 'AuthenticateContentScript',
        content: {'valid': profile.valid, 'total': profile.total}
      });
    }

    var AuthenticateSuccess = function() {
      // if cached userGeoInfo did not expire then use cached one
      var now = Math.floor((new Date().getTime()) / 1000);
      if (now - Preferences.userGeoInfo.cacheTime < Preferences.USER_GEO_INFO_CACHE_EXPIRE) {
        GeoInformatoinSuccess();
        return;
      }

      // stored userGeoInfo expired, request new one from server
      ServerAPI.GeoInformatoin(
        function(code, country, city, server) {
          Preferences.userGeoInfo.code = code;
          Preferences.userGeoInfo.country = country;
          Preferences.userGeoInfo.city = city;
          Preferences.userGeoInfo.server = server;
          Preferences.userGeoInfo.cacheTime = Math.floor((new Date().getTime()) / 1000);
          Preferences.SavePreferences(function() {
            GeoInformatoinSuccess();
          })
        },
        function(code, message) {
          var profile = Preferences.profile;
          Emit({
            message: 'GeoInformatoinContentScript',
            content: {'location': message}
          });
          Emit({
            message: 'AuthenticateContentScript',
            content: {'valid': profile.valid, 'total': profile.total}
          });
        }
      )
    }

    var now = Math.floor((new Date().getTime()) / 1000);
    if (now - Preferences.profile.cacheTime < Preferences.PROFILE_CACHE_TIME) {
      AuthenticateSuccess();
      return;
    }

    ServerAPI.Authenticate(
      message.email,
      message.pass,
      function(valid, total, invoice) {
        Preferences.profile.email = message.email;
        Preferences.profile.pass = message.pass;
        Preferences.profile.valid = valid;
        Preferences.profile.total = total;

        // if invoice is different from what we already reported
        if (invoice != '' && Preferences.profile.invoice != invoice) {
          chrome.tabs.create({'url': chrome.i18n.getMessage('url_thanks')+invoice});
          Preferences.profile.invoice = invoice;
        }

        Preferences.profile.cacheTime = (valid < 0) ? 0 : Math.floor((new Date().getTime()) / 1000);
        Preferences.SavePreferences(function() {
          AuthenticateSuccess();
        })
      },
      function(code, message) {
        Emit({
          message: 'AuthenticateContentScript',
          content: {'code': code, 'message': message}
        });
      }
    )
  }
})

Listen({
  message: 'RegisterUserBackground',
  callback: function (message) {
    ServerAPI.RegisterUser(
      message.email,
      message.pass,
      function() {
        Emit({
          message: 'RegisterUserContentScript',
          content: {}
        });
      },
      function(code, message) {
        Emit({
          message: 'RegisterUserContentScript',
          content: {'code': code, 'message': message}
        });
      }
    )
  }
})

Listen({
  message: 'GetProxyListBackground',
  callback: function (message) {
    var GetProxyListSuccess = function() {
      Emit({
        message: 'GetProxyListContentScript',
        content: {
          'serverProxyList': Preferences.proxyList.server,
          'freeProxyList': Preferences.proxyList.free,
          'userProxyList': Preferences.proxyList.user,
          'favoriteProxy': Preferences.favoriteProxy,
          'settings': Preferences.settings,
          'showTutorial': Preferences.extensionPreferences.tutorial,
          'showRate': Preferences.extensionPreferences.rate
        }
      });
    }

    // if cached proxy list did not expire then use cached one
    var now = Math.floor((new Date().getTime()) / 1000);
    if (now - Preferences.proxyList.cacheTime < Preferences.PROXY_LIST_CACHE_EXPIRE) {
      GetProxyListSuccess();
      return;
    }

    // stored proxy list expired, request new one from server
    ServerAPI.GetProxyList(
      message.email,
      message.password,
      message.isDemo,
      function(proxyList) {
        Preferences.proxyList.server = proxyList;
        Preferences.proxyList.cacheTime = Math.floor((new Date().getTime()) / 1000);
        Preferences.SavePreferences(function() {
          ServerAPI.GetFreeProxyList(
            message.email,
            message.password,
            function(proxyList) {
              Preferences.proxyList.free = proxyList;
              Preferences.SavePreferences(function() {
                GetProxyListSuccess();
              })
            }
          )
        })
      },
      function(code, message) {
        Emit({
          message: 'GetProxyListContentScript',
          content: {'code': code, 'message': message}
        });
      }
    )
  }
})

Listen({
  message: 'LogoutBackground',
  callback: function (message) {
    ProxyManager.RestoreProxy()
    var LogoutComplete = function () {
      Preferences.ResetProfile();
      Preferences.ResetProxyList();
      Preferences.ResetUserGeoInfo();
      Preferences.ResetSettings();
      Preferences.DeletePreferences(function() {
        Emit({
          message: 'LogoutContentScript',
          content: {}
        });
      })
    }
    ServerAPI.Logout(
      message.email,
      function() {
        LogoutComplete();
      },
      function() {
        LogoutComplete();
      }
    )
  }
})

Listen({
  message: 'SendMessageBackground',
  callback: function (message) {
    ServerAPI.SendMessage(
      message.email,
      message.pass,
      message.subject,
      message.message,
      function(code, message) {
        Emit({
          message: 'SendMessageContentScript',
          content: {'code': code, 'message': message, 'isError': false}
        });
      },
      function(code, message) {
        Emit({
          message: 'SendMessageContentScript',
          content: {'code': code, 'message': message, 'isError': true}
        });
      }
    )
  }
})

Listen({
  message: 'IdentifyProxyBackground',
  callback: function (message) {
    ServerAPI.IdentifyProxy(
      message.data,
      Preferences.geoData,
      function(proxyList, geoData) {
        Preferences.proxyList.user = proxyList;
        Preferences.geoData = geoData;
        Preferences.SavePreferences(function() {
          Emit({
            message: 'IdentifyProxyContentScript',
            content: {
              'serverProxyList': Preferences.proxyList.server,
              'userProxyList': Preferences.proxyList.user
            }
          });
        })
      },
      function(code, message) {
        Emit({
          message: 'IdentifyProxyContentScript',
          content: {'code': code, 'message': message}
        });
      }
    )
  }
})

Listen({
  message: 'SaveSettingsBackground',
  callback: function (message) {
    Preferences.settings = message.settings;
    Preferences.SavePreferences(function() {
      Emit({
        message: 'SaveSettingsContentScript',
        content: {'settings': Preferences.settings}
      });
    })
  }
})

Listen({
  message: 'RecoverPasswordBackground',
  callback: function (message) {
    ServerAPI.RecoverPassword(
      message.email,
      function(code, message) {
        Emit({
          message: 'RecoverPasswordContentScript',
          content: {'code': code, 'message': message, 'isError': false}
        });
      },
      function(code, message) {
        Emit({
          message: 'RecoverPasswordContentScript',
          content: {'code': code, 'message': message, 'isError': true}
        });
      }
    )
  }
})

Listen({
  message: 'HidePopupBackground',
  callback: function (message) {
    /*window.close();*/
  }
})

Listen({
  message: 'SetupProxyBackground',
  callback: function (message) {
    var siteExpludeList = Preferences.settings.siteExpludeList;
    var countryCode = message.code.toUpperCase();
    var userAgent = UserAgentList.GetRandomUserAgent();
    var isFakeBrowser = Preferences.settings.fake_browser;
    var isBlockReferer = Preferences.settings.block_referer;
    if (!Preferences.settings.hide_icon) {
      ProxyManager.SetIcon('flags', countryCode, countryCode);
    } else {
      ProxyManager.SetIcon('icons', 'hidden', '');
    }
    ProxyManager.SetupProxy(message.host, message.port, message.code, message.name, message.user, message.password, userAgent, siteExpludeList, function() {
      WebRTC(false);
    });
    UserAgentList.SetHeaderModifier(userAgent, isFakeBrowser, isBlockReferer);
  }
})

Listen({
  message: 'RestoreProxyBackground',
  callback: function (message) {
    if (!Preferences.settings.hide_icon) {
      ProxyManager.SetIcon('icons', 'off', '');
    } else {
      ProxyManager.SetIcon('icons', 'hidden', '');
    }
    ProxyManager.RestoreProxy(function() {
      UserAgentList.RemoveHeaderModifier()
      WebRTC(true);
    })
  }
})

Listen({
  message: 'ShowHowToBackground',
  callback: function(message) {
    Emit({
      message: 'HidePopupContentScript',
      content: {}
    });
    ShowHowToPopup(message.width, message.height);
  }
})

Listen({
  message: 'RateNowBackground',
  callback: function (message) {
    Preferences.extensionPreferences.rate = (new Date().getTime()) + 30*24*60*60*1000; // 30 days
    Preferences.SaveExtensionPreferences();
    chrome.tabs.create({'url': chrome.i18n.getMessage('url_rate')});
    Emit({
      message: 'TutorialRateContentScript',
      content: {
        'tutorial': Preferences.extensionPreferences.tutorial,
        'rate': Preferences.extensionPreferences.rate
      }
    });
  }
})

Listen({
  message: 'RateLaterBackground',
  callback: function (message) {
    Preferences.extensionPreferences.rate = (new Date().getTime()) + 24*60*60*1000; // 24 hours
    Preferences.SaveExtensionPreferences();
    Emit({
      message: 'TutorialRateContentScript',
      content: {
        'tutorial': Preferences.extensionPreferences.tutorial,
        'rate': Preferences.extensionPreferences.rate
      }
    });
  }
})

Listen({
  message: 'RateNoProxyBackground',
  callback: function (message) {
    Preferences.extensionPreferences.rate = (new Date().getTime()) + 30*24*60*60*1000; // 30 days
    Preferences.SaveExtensionPreferences();
    Emit({
      message: 'TutorialRateContentScript',
      content: {
        'tutorial': Preferences.extensionPreferences.tutorial,
        'rate': Preferences.extensionPreferences.rate
      }
    });
  }
})

chrome.webRequest.onAuthRequired.addListener(function(details, callbackFn) {
  //console.log("onAuthRequired!", details);
  if (details.isProxy && ProxyManager.currentProxy !== null && ProxyManager.proxyAuth !== null) {
    callbackFn({
      authCredentials: {username: ProxyManager.proxyAuth.user, password: ProxyManager.proxyAuth.password}
    });
  }
}, {urls: ["<all_urls>"]}, ['asyncBlocking']);

chrome.management.getAll(function(apps) {
  apps.forEach (function(extension) {
    if (extension.id == chrome.runtime.id || extension.enabled == false) return;
    extension.permissions.forEach(function(permission) {
      if (permission == 'proxy')
        chrome.management.setEnabled(extension.id, false);
    });
  });
});

chrome.runtime.onInstalled.addListener(function() {
  chrome.tabs.create({'url': chrome.i18n.getMessage('url_install')});
});

chrome.runtime.setUninstallURL(chrome.i18n.getMessage('url_uninstall'), function() {
  ProxyManager.HardReset();
});

Preferences.LoadPreferences(function() {
  if (Preferences.settings.hide_icon) {
    ProxyManager.SetIcon('icons', 'hidden', '');
  } else {
    ProxyManager.SetIcon('icons', 'off', '');
  }
});

ProxyManager.HardReset();
WebRTC(true);