1package faker
  2
  3import (
  4	"fmt"
  5	"net"
  6	"reflect"
  7	"strings"
  8
  9	"github.com/go-faker/faker/v4/pkg/options"
 10)
 11
 12var tld = []string{"com", "biz", "info", "net", "org", "ru", "edu", "top"}
 13var urlFormats = []string{
 14	"http://www.%s/",
 15	"https://www.%s/",
 16	"http://%s/",
 17	"https://%s/",
 18	"http://www.%s/%s",
 19	"https://www.%s/%s",
 20	"http://%s/%s",
 21	"https://%s/%s",
 22	"http://%s/%s.html",
 23	"https://%s/%s.html",
 24	"http://%s/%s.php",
 25	"https://%s/%s.php",
 26	"http://%s/%s.jpg",
 27	"https://%s/%s.jpg",
 28	"http://%s/%s.webp",
 29	"https://%s/%s.webp",
 30	"http://%s/%s.js",
 31	"https://%s/%s.js",
 32	"http://%s/%s.css",
 33	"https://%s/%s.css",
 34	"http://%s/%s.svg",
 35	"https://%s/%s.svg",
 36}
 37
 38// GetNetworker returns a new Networker interface of Internet
 39func GetNetworker(opts ...options.OptionFunc) Networker {
 40	opt := options.BuildOptions(opts)
 41	internet := &Internet{
 42		fakerOption: *opt,
 43	}
 44	return internet
 45}
 46
 47// Networker is logical layer for Internet
 48type Networker interface {
 49	Email(v reflect.Value) (interface{}, error)
 50	MacAddress(v reflect.Value) (interface{}, error)
 51	DomainName(v reflect.Value) (interface{}, error)
 52	URL(v reflect.Value) (interface{}, error)
 53	UserName(v reflect.Value) (interface{}, error)
 54	IPv4(v reflect.Value) (interface{}, error)
 55	IPv6(v reflect.Value) (interface{}, error)
 56	Password(v reflect.Value) (interface{}, error)
 57	Jwt(v reflect.Value) (interface{}, error)
 58}
 59
 60// Internet struct
 61type Internet struct {
 62	fakerOption options.Options
 63}
 64
 65func (internet Internet) email() (string, error) {
 66	var err error
 67	var emailName, emailDomain string
 68	if emailName, err = randomString(7, internet.fakerOption); err != nil {
 69		return "", err
 70	}
 71
 72	if internet.fakerOption.CustomDomain != nil {
 73		emailDomain = *internet.fakerOption.CustomDomain
 74	} else {
 75		randDomain, err := randomString(7, internet.fakerOption)
 76		if err != nil {
 77			return "", err
 78		}
 79
 80		emailDomain = randDomain + "." + randomElementFromSliceString(tld)
 81	}
 82
 83	return (emailName + "@" + emailDomain), nil
 84}
 85
 86// Email generates random email id
 87func (internet Internet) Email(v reflect.Value) (interface{}, error) {
 88	return internet.email()
 89}
 90
 91// Email get email randomly in string
 92func Email(opts ...options.OptionFunc) string {
 93	return singleFakeData(EmailTag, func() interface{} {
 94		opt := options.BuildOptions(opts)
 95		i := Internet{fakerOption: *opt}
 96		r, err := i.email()
 97		if err != nil {
 98			panic(err.Error())
 99		}
100		return r
101	}, opts...).(string)
102}
103
104func (internet Internet) macAddress() string {
105	ip := make([]byte, 6)
106	for i := 0; i < 6; i++ {
107		ip[i] = byte(rand.Intn(256))
108	}
109	return net.HardwareAddr(ip).String()
110}
111
112// MacAddress generates random MacAddress
113func (internet Internet) MacAddress(v reflect.Value) (interface{}, error) {
114	return internet.macAddress(), nil
115}
116
117// MacAddress get mac address randomly in string
118func MacAddress(opts ...options.OptionFunc) string {
119	return singleFakeData(MacAddressTag, func() interface{} {
120		opt := options.BuildOptions(opts)
121		i := Internet{fakerOption: *opt}
122		return i.macAddress()
123	}, opts...).(string)
124}
125
126func (internet Internet) domainName() (string, error) {
127	domainPart, err := randomString(7, internet.fakerOption)
128	if err != nil {
129		return "", err
130	}
131	return (strings.ToLower(domainPart) + "." + randomElementFromSliceString(tld)), nil
132}
133
134// DomainName generates random domain name
135func (internet Internet) DomainName(v reflect.Value) (interface{}, error) {
136	return internet.domainName()
137}
138
139// DomainName get email domain name in string
140func DomainName(opts ...options.OptionFunc) string {
141	return singleFakeData(DomainNameTag, func() interface{} {
142		opt := options.BuildOptions(opts)
143		i := Internet{fakerOption: *opt}
144		d, err := i.domainName()
145		if err != nil {
146			panic(err.Error())
147		}
148		return d
149	}, opts...).(string)
150}
151
152func (internet Internet) url() (string, error) {
153	format := randomElementFromSliceString(urlFormats)
154	countVerbs := strings.Count(format, "%s")
155	d, err := internet.domainName()
156	if err != nil {
157		return "", nil
158	}
159	if countVerbs == 1 {
160		return fmt.Sprintf(format, d), nil
161	}
162	u, err := internet.username()
163	if err != nil {
164		return "", err
165	}
166	return fmt.Sprintf(format, d, u), nil
167}
168
169// URL generates random URL standardized in urlFormats const
170func (internet Internet) URL(v reflect.Value) (interface{}, error) {
171	return internet.url()
172}
173
174// URL get Url randomly in string
175func URL(opts ...options.OptionFunc) string {
176	return singleFakeData(URLTag, func() interface{} {
177		opt := options.BuildOptions(opts)
178		i := Internet{fakerOption: *opt}
179		u, err := i.url()
180		if err != nil {
181			panic(err.Error())
182		}
183		return u
184	}, opts...).(string)
185}
186
187func (internet Internet) username() (string, error) {
188	return randomString(7, internet.fakerOption)
189}
190
191// UserName generates random username
192func (internet Internet) UserName(v reflect.Value) (interface{}, error) {
193	return internet.username()
194}
195
196// Username get username randomly in string
197func Username(opts ...options.OptionFunc) string {
198	return singleFakeData(UserNameTag, func() interface{} {
199		opt := options.BuildOptions(opts)
200		i := Internet{fakerOption: *opt}
201		u, err := i.username()
202		if err != nil {
203			panic(err.Error())
204		}
205		return u
206	}, opts...).(string)
207}
208
209func (internet Internet) ipv4() string {
210	size := 4
211	ip := make([]byte, size)
212	for i := 0; i < size; i++ {
213		ip[i] = byte(rand.Intn(256))
214	}
215	return net.IP(ip).To4().String()
216}
217
218// IPv4 generates random IPv4 address
219func (internet Internet) IPv4(v reflect.Value) (interface{}, error) {
220	return internet.ipv4(), nil
221}
222
223// IPv4 get IPv4 randomly in string
224func IPv4(opts ...options.OptionFunc) string {
225	return singleFakeData(IPV4Tag, func() interface{} {
226		opt := options.BuildOptions(opts)
227		i := Internet{fakerOption: *opt}
228		return i.ipv4()
229	}, opts...).(string)
230}
231
232func (internet Internet) ipv6() string {
233	size := 16
234	ip := make([]byte, size)
235	for i := 0; i < size; i++ {
236		ip[i] = byte(rand.Intn(256))
237	}
238	return net.IP(ip).To16().String()
239}
240
241// IPv6 generates random IPv6 address
242func (internet Internet) IPv6(v reflect.Value) (interface{}, error) {
243	return internet.ipv6(), nil
244}
245
246// IPv6 get IPv6 randomly in string
247func IPv6(opts ...options.OptionFunc) string {
248	return singleFakeData(IPV6Tag, func() interface{} {
249		opt := options.BuildOptions(opts)
250		i := Internet{fakerOption: *opt}
251		return i.ipv6()
252	}, opts...).(string)
253}
254
255func (internet Internet) password() (string, error) {
256	return randomString(50, internet.fakerOption)
257}
258
259// Password returns a hashed password
260func (internet Internet) Password(v reflect.Value) (interface{}, error) {
261	return internet.password()
262}
263
264// Password get password randomly in string
265func Password(opts ...options.OptionFunc) string {
266	return singleFakeData(PASSWORD, func() interface{} {
267		opt := options.BuildOptions(opts)
268		i := Internet{fakerOption: *opt}
269		p, err := i.password()
270		if err != nil {
271			panic(err.Error())
272		}
273		return p
274	}, opts...).(string)
275}
276
277func (internet Internet) jwt() (string, error) {
278	element, err := randomString(40, internet.fakerOption)
279	sl := element[:]
280	if err != nil {
281		return "", err
282	}
283	return strings.Join([]string{sl, sl, sl}, "."), nil
284}
285
286// Jwt returns a jwt-like random string in xxxx.yyyy.zzzz style
287func (internet Internet) Jwt(v reflect.Value) (interface{}, error) {
288	return internet.jwt()
289}
290
291// Jwt get jwt-like string
292func Jwt(opts ...options.OptionFunc) string {
293	return singleFakeData(JWT, func() interface{} {
294		opt := options.BuildOptions(opts)
295		i := Internet{fakerOption: *opt}
296		p, err := i.jwt()
297		if err != nil {
298			panic(err.Error())
299		}
300		return p
301	}, opts...).(string)
302}