1/*
2 Copyright (C) 2018 Christian Dywan <christian@twotoats.de>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 See the file COPYING for the full license text.
10*/
11
12namespace Adblock {
13    public class Settings : Midori.Settings {
14        static Settings? _default = null;
15        public string default_filters = "https://easylist.to/easylist/easylist.txt&title=EasyList;https://easylist.to/easylist/easyprivacy.txt&title=EasyPrivacy";
16        List<Subscription> subscriptions;
17
18        public static Settings get_default () {
19            if (_default == null) {
20                string filename = Path.build_filename (Environment.get_user_config_dir (),
21                    Config.PROJECT_NAME, "extensions", "libadblock.so", "config");
22                _default = new Settings (filename);
23            }
24            return _default;
25        }
26
27        Settings (string filename) {
28            Object (filename: filename);
29            string[] filters = get_string ("settings", "filters", default_filters).split (";");
30            foreach (unowned string filter in filters) {
31                if (filter == "") {
32                    continue;
33                }
34
35                string uri = filter;
36                if (filter.has_prefix ("http-/")) {
37                    uri = "http:" + filter.substring (5);
38                } else if (filter.has_prefix ("file-/")) {
39                    uri = "file:" + filter.substring (5);
40                } else if (filter.has_prefix ("http-:")) {
41                    uri = "https" + filter.substring (5);
42                }
43                add (new Subscription (uri, filter == uri));
44            }
45            // Always add the default filters in case they were removed
46            foreach (unowned string uri in default_filters.split (";")) {
47                add (new Subscription (uri));
48            }
49        }
50
51        public bool enabled { get {
52            return !get_boolean ("settings", "disabled", false);
53        } set {
54            set_boolean ("settings", "disabled", !value, false);
55        } }
56
57        /* foreach support */
58        public new unowned Subscription? get (uint index) {
59            return subscriptions.nth_data (index);
60        }
61        public uint size { get; private set; }
62
63        public bool contains (Subscription subscription) {
64            foreach (unowned Subscription sub in subscriptions) {
65                if (sub.file.get_path () == subscription.file.get_path ())
66                    return true;
67            }
68            return false;
69        }
70
71        public void add (Subscription sub) {
72            if (contains (sub)) {
73                return;
74            }
75
76            sub.notify["active"].connect (active_changed);
77            subscriptions.append (sub);
78            size++;
79        }
80
81        void active_changed () {
82            var filters = new StringBuilder ();
83            foreach (unowned Subscription sub in subscriptions) {
84                if (sub.uri.has_prefix ("http:") && !sub.active) {
85                    filters.append ("http-" + sub.uri.substring (4));
86                } else if (sub.uri.has_prefix ("file:") && !sub.active) {
87                    filters.append ("file-" + sub.uri.substring (5));
88                } else if (sub.uri.has_prefix ("https:") && !sub.active) {
89                    filters.append ("http-" + sub.uri.substring (5));
90                } else {
91                    filters.append (sub.uri);
92                }
93                filters.append_c (';');
94            }
95
96            if (filters.str.has_suffix (";"))
97                filters.truncate (filters.len - 1);
98            set_string ("settings", "filters", filters.str);
99        }
100
101        public void remove (Subscription sub) {
102            subscriptions.remove (sub);
103            size--;
104            sub.notify["active"].disconnect (active_changed);
105            active_changed ();
106        }
107    }
108}
109